From 81c9ba22a754b4dcfb0968599d497d0cda85e3b1 Mon Sep 17 00:00:00 2001 From: albert Date: Sat, 23 Feb 2013 20:08:20 -0500 Subject: [PATCH] add wiki diff --- Gemfile | 1 + Gemfile.lock | 2 + .../stylesheets/specific/wiki_pages.css.scss | 14 +++++ .../wiki_page_versions_controller.rb | 5 ++ app/helpers/wiki_page_versions_helper.rb | 49 +++++++++++++++ app/models/wiki_page_version.rb | 2 +- app/views/wiki_page_versions/diff.html.erb | 13 ++++ app/views/wiki_page_versions/index.html.erb | 62 +++++++++++-------- config/routes.rb | 6 +- 9 files changed, 125 insertions(+), 29 deletions(-) create mode 100644 app/views/wiki_page_versions/diff.html.erb diff --git a/Gemfile b/Gemfile index 1c9523ed2..4dc1845f1 100644 --- a/Gemfile +++ b/Gemfile @@ -31,6 +31,7 @@ gem 'net-ssh' gem 'net-sftp' gem 'newrelic_rpm' gem 'term-ansicolor', :require => "term/ansicolor" +gem 'diff-lcs', :require => "diff/lcs/array" group :development do gem 'ruby-prof' diff --git a/Gemfile.lock b/Gemfile.lock index 04de5f7a5..bd9ad37f6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,6 +66,7 @@ GEM delayed_job_active_record (0.4.1) activerecord (>= 2.1.0, < 4) delayed_job (~> 3.0) + diff-lcs (1.2.1) domain_name (0.5.7) unf (~> 0.0.3) erubis (2.7.0) @@ -188,6 +189,7 @@ DEPENDENCIES daemons delayed_job delayed_job_active_record + diff-lcs factory_girl ffaker! mechanize! diff --git a/app/assets/stylesheets/specific/wiki_pages.css.scss b/app/assets/stylesheets/specific/wiki_pages.css.scss index 8f4ce651c..f9bc3da81 100644 --- a/app/assets/stylesheets/specific/wiki_pages.css.scss +++ b/app/assets/stylesheets/specific/wiki_pages.css.scss @@ -7,4 +7,18 @@ div#c-wiki-pages { float: left; width: 30em; } + + del { + background: #FCC; + text-decoration: none; + } + + ins { + background: #CFC; + text-decoration: none; + } + + table { + margin-bottom: 1em; + } } \ No newline at end of file diff --git a/app/controllers/wiki_page_versions_controller.rb b/app/controllers/wiki_page_versions_controller.rb index cf0e260fe..d53767c5c 100644 --- a/app/controllers/wiki_page_versions_controller.rb +++ b/app/controllers/wiki_page_versions_controller.rb @@ -10,4 +10,9 @@ class WikiPageVersionsController < ApplicationController @wiki_page_version = WikiPageVersion.find(params[:id]) respond_with(@wiki_page_version) end + + def diff + @thispage = WikiPageVersion.find(params[:thispage]) + @otherpage = WikiPageVersion.find(params[:otherpage]) + end end diff --git a/app/helpers/wiki_page_versions_helper.rb b/app/helpers/wiki_page_versions_helper.rb index eacae640e..fa8e9c28f 100644 --- a/app/helpers/wiki_page_versions_helper.rb +++ b/app/helpers/wiki_page_versions_helper.rb @@ -1,2 +1,51 @@ module WikiPageVersionsHelper + def wiki_page_diff(thispage, otherpage) + pattern = Regexp.new('(?:<.+?>)|(?:\w+)|(?:[ \t]+)|(?:\r?\n)|(?:.+?)') + + thisarr = thispage.body.scan(pattern) + otharr = otherpage.body.scan(pattern) + + cbo = Diff::LCS::ContextDiffCallbacks.new + diffs = thisarr.diff(otharr, cbo) + + escape_html = lambda {|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]}") + 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/models/wiki_page_version.rb b/app/models/wiki_page_version.rb index 21de3f0e0..003e61439 100644 --- a/app/models/wiki_page_version.rb +++ b/app/models/wiki_page_version.rb @@ -24,7 +24,7 @@ class WikiPageVersion < ActiveRecord::Base end extend SearchMethods - + def updater_name User.id_to_name(updater_id) end diff --git a/app/views/wiki_page_versions/diff.html.erb b/app/views/wiki_page_versions/diff.html.erb new file mode 100644 index 000000000..b5b3cb9fc --- /dev/null +++ b/app/views/wiki_page_versions/diff.html.erb @@ -0,0 +1,13 @@ +
+
+

Wiki Page: <%= @thispage.title %>

+ +

Showing differences between <%= compact_time @thispage.created_at %> (<%= link_to @thispage.updater.name, user_path(@thispage.updater) %>) and <%= compact_time @otherpage.created_at %> (<%= link_to @otherpage.updater.name, user_path(@otherpage.updater) %>)

+ +
+ <%= wiki_page_diff(@thispage, @otherpage) %> +
+
+
+ +<%= render "wiki_pages/secondary_links" %> \ No newline at end of file diff --git a/app/views/wiki_page_versions/index.html.erb b/app/views/wiki_page_versions/index.html.erb index c51dc95fe..9639c5c06 100644 --- a/app/views/wiki_page_versions/index.html.erb +++ b/app/views/wiki_page_versions/index.html.erb @@ -5,34 +5,42 @@

Wiki Pages

- - - - - - - - - - <% @wiki_page_versions.each do |wiki_page_version| %> + <%= form_tag(diff_wiki_page_versions_path, :method => :get) do %> +
TitleIP AddressLast edited
+ - - - - - <% end %> - -
<%= wiki_page_version.title %> - <% if CurrentUser.is_admin? %> - <%= wiki_page_version.updater_ip_addr %> - <% end %> - - <%= link_to wiki_page_version.updated_at.strftime("%Y-%m-%d %I:%M"), wiki_page_version_path(wiki_page_version) %> - <% if wiki_page_version.updater %> - by - <%= link_to wiki_page_version.updater_name, user_path(wiki_page_version.updater) %> - <% end %> -
+ + + Title + IP Address + Last edited + + + + <% @wiki_page_versions.each do |wiki_page_version| %> + + <%= radio_button_tag "thispage", wiki_page_version.id %> + <%= radio_button_tag "otherpage", wiki_page_version.id %> + <%= wiki_page_version.title %> + + <% if CurrentUser.is_admin? %> + <%= wiki_page_version.updater_ip_addr %> + <% end %> + + + <%= link_to wiki_page_version.updated_at.strftime("%Y-%m-%d %I:%M"), wiki_page_version_path(wiki_page_version) %> + <% if wiki_page_version.updater %> + by + <%= link_to wiki_page_version.updater_name, user_path(wiki_page_version.updater) %> + <% end %> + + + <% end %> + + + + <%= submit_tag "Diff" %> + <% end %> <%= numbered_paginator(@wiki_page_versions) %>
diff --git a/config/routes.rb b/config/routes.rb index 4321e3159..53ae16002 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -193,7 +193,11 @@ Danbooru::Application.routes.draw do get :show_or_new end end - resources :wiki_page_versions, :only => [:index, :show] + resources :wiki_page_versions, :only => [:index, :show, :diff] do + collection do + get :diff + end + end # aliases resources :wpages, :controller => "wiki_pages"