Kouhei Sutou
kou****@cozmi*****
2005年 2月 8日 (火) 01:01:16 JST
須藤です. 以前[Hiki-dev:00538](*)で提案したやつですが,やっぱり,今の編集 履歴のインターフェイスは(_私にとって_)使いづらいのでもう一 度提案します. 主な使いづらさは * 一つずつ編集履歴を辿っていく(差分を表示していく)ときに いちいち編集履歴一覧ページに戻らないといけないのが嫌 ということです. 添付のパッチをあてると編集履歴一覧ページ/diffページ/ソース 表示ページにいろいろリンクが増えます. == 編集履歴一覧ページ * 元のページへのリンク == diffページ * 元のページへのリンク * 前後のリビジョンでのdiffを表示するページへのリンク * 現在のリビジョンのソースを表示するページへのリンク == ソース表示ページ * 元のページへのリンク パッチをあてた後のサンプルは以下のURLで確認できます. http://pub.cozmixng.org/~hiki/test/?c=history;p=FrontPage -- (*) http://yowaken.dip.jp/w3ml/hiki-dev/msg/538 -------------- next part -------------- Index: misc/plugin/history.rb =================================================================== RCS file: /cvsroot/hiki/hiki/misc/plugin/history.rb,v retrieving revision 1.16 diff -u -p -r1.16 history.rb --- misc/plugin/history.rb 6 Jan 2005 10:30:52 -0000 1.16 +++ misc/plugin/history.rb 7 Feb 2005 15:53:48 -0000 @@ -97,7 +97,7 @@ module Hiki def history_th_label # ['Rev', 'Time(GMT)', 'Changes', 'Operation', 'Log'] - ['Rev', '時刻(GMT)', '変更', '操作', 'ログ'] + ['Rev', '時刻', '変更', '操作', 'ログ'] end def history_not_supported_label @@ -108,6 +108,10 @@ module Hiki '現在のバージョンとの差分を見る' end + def history_view_this_version_src_label + 'このバージョンのソースを見る' + end + def history_backto_summary_label '編集履歴ページに戻る' end @@ -152,15 +156,7 @@ module Hiki generate_page(data) # private method inherited from Command class end - - public - - # Output summary of change history - def history - unless history_repos_root then - return history_output(history_not_supported_label) - end - + def revisions # make command string case history_repos_type when 'cvs' @@ -168,30 +164,87 @@ module Hiki when 'svn' hstcmd = "svn log #{@p.escape}" else - return history_output(history_not_supported_label) + raise end - + # invoke external command cmdlog = history_exec_command(hstcmd) - + # parse the result and make revisions array - revisions = Array::new() + parse_history(cmdlog) + end + + def parse_history(cmdlog) + revs = [] + diffrevs = [] case history_repos_type when 'cvs' cmdlog.split(/----------------------------/).each do |tmp| if /revision 1.(\d+?)\ndate: (.*?); author: (?:.*?); state: (?:.*?);(.*?)?\n(.*)/m =~ tmp then - revisions << [$1.to_i, $2, $3, $4] + revs << [$1.to_i, Time.parse("#{$2}Z").localtime.to_s, $3, $4] end end when 'svn' - diffrevs = [] cmdlog.split(/------------------------------------------------------------------------/).each do |tmp| if /(?:\D+)(\d+?)[\s:\|]+[(?:\s)*](?:.*?) \| (.*?)(?: \(.+\))? \| (.*?)\n(.*?)\n/m =~ tmp then - revisions << [$1.to_i, $2, $3, $4] + revs << [$1.to_i, Time.parse("#{$2}Z").localtime.to_s, $3, $4] diffrevs << $1.to_i end end end + [revs, diffrevs] + end + + def recent_revs(revs, rev) + ind = revs.index(revs.assoc(rev)) || 0 + prev_rev = revs[ind + 1] + prev2_rev = revs[ind + 2] + if ind - 1 >= 0 + next_rev = revs[ind - 1] + else + next_rev = nil + end + [prev2_rev, prev_rev, revs[ind], next_rev] + end + + def diff_link(rev1, rev2, rev_title1, rev_title2, link) + title = [] + title << (rev_title1 || (rev1 and rev1[0]) || nil) + title << (rev_title2 || (rev2 and rev2[0]) || nil) + title = title.compact + title.reverse! unless rev2.nil? + title = title.join("<=>").escapeHTML + + do_link = (link and rev1) + + rv = "[" + if do_link + rev_param = "r=#{rev1[0]}" + rev_param << ";r2=#{rev2[0]}" if rev2 + rv << %Q[<a href="#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};#{rev_param}")}" title="#{title}">] + end + rv << title + if do_link + rv << "</a>" + end + rv << "]\n" + rv + end + + public + + # Output summary of change history + def history + unless history_repos_root then + return history_output(history_not_supported_label) + end + + unless %w(cvs svn).include?(history_repos_type) + return history_output(history_not_supported_label) + end + + # parse the result and make revisions array + revs, diffrevs = revisions # construct output sources if history_repos_type == 'svn' then @@ -201,20 +254,22 @@ module Hiki # sources << "<pre>\n" # sources << cmdlog # sources << "</pre>\n" + sources << @plugin.hiki_anchor(@p.escape, @plugin.page_name(@p)) + sources << "\n<br>\n" sources << "\n<table border=\"1\">\n" if****@conf*****['history.hidelog'] sources << " <tr><th>#{history_th_label[0].escapeHTML}</th><th>#{history_th_label[1].escapeHTML}</th><th>#{history_th_label[2].escapeHTML}</th><th>#{history_th_label[3].escapeHTML}</th></tr>\n" else sources << " <tr><th rowspan=\"2\">#{history_th_label[0].escapeHTML}</th><th>#{history_th_label[1].escapeHTML}</th><th>#{history_th_label[2].escapeHTML}</th><th>#{history_th_label[3].escapeHTML}</th></tr><tr><th colspan=\"3\">#{history_th_label[4].escapeHTML}</th></tr>\n" end - revisions.each do |rev,time,changes,log| + revs.each do |rev,time,changes,log| # time << " GMT" op = "[<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_src;p=#{@p.escape};r=#{rev}")}\">View</a> this version] " op << "[Diff to " case history_repos_type when 'cvs' - op << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};r=#{rev}")}\">current</a>" unless revisions.size == rev - op << " | " unless (revisions.size == rev || rev == 1) + op << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};r=#{rev}")}\">current</a>" unless revs.size == rev + op << " | " unless (revs.size == rev || rev == 1) op << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};r=#{rev};r2=#{rev-1}")}\">previous</a>" unless rev == 1 when 'svn' op << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};r=#{rev}")}\">current</a>" unless prevdiff == 1 @@ -263,6 +318,8 @@ module Hiki # construct output sources sources = '' sources << "<div class=\"section\">\n" + sources << @plugin.hiki_anchor(@p.escape, @plugin.page_name(@p)) + sources << "\n<br>\n" sources << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_diff;p=#{@p.escape};r=#{r.escapeHTML}")}\">#{history_diffto_current_label.escapeHTML}</a><br>\n" sources << "<a href=\"#{@conf.cgi_name}#{cmdstr('history', "p=#{@p.escape}")}\">#{history_backto_summary_label.escapeHTML}</a><br>\n" sources << "</div>\n" @@ -279,6 +336,10 @@ module Hiki return history_output(history_not_supported_label) end + unless %w(cvs svn).include?(history_repos_type) + return history_output(history_not_supported_label) + end + # make command string r =****@cgi*****['r'][0] || '1' r2 =****@cgi*****['r2'][0] @@ -303,12 +364,37 @@ module Hiki return history_output(history_not_supported_label) end + # parse the result and make revisions array + revs, diffrevs = revisions + + prev2_rev, prev_rev, curr_rev, next_rev = recent_revs(revs, r.to_i) + last_rev = revs[0] + diff = word_diff( old, new ) # construct output sources sources = '' sources << "<div class=\"section\">\n" + sources << @plugin.hiki_anchor(@p.escape, @plugin.page_name(@p)) + sources << "<br>\n" + sources << "<a href=\"#{@conf.cgi_name}#{cmdstr('plugin', "plugin=history_src;p=#{@p.escape};r=#{curr_rev[0]}")}\">#{history_view_this_version_src_label.escapeHTML}</a><br>\n" if curr_rev sources << "<a href=\"#{@conf.cgi_name}#{cmdstr('history', "p=#{@p.escape}")}\">#{history_backto_summary_label.escapeHTML}</a><br>\n" + sources << "\n" + + if prev_rev + do_link = (last_rev and prev_rev and last_rev[0] != prev_rev[0]) + sources << diff_link(prev_rev, nil, nil, "HEAD", do_link) + end + if prev_rev and prev2_rev + sources << diff_link(prev_rev, prev2_rev, nil, nil, true) + end + sources << diff_link(curr_rev, r2.nil? ? nil : prev_rev, nil, nil, false) + if next_rev + sources << diff_link(next_rev, curr_rev, nil, nil, true) + end + do_link = (r2 and last_rev and last_rev[0] != curr_rev[0]) + sources << diff_link(curr_rev, nil, nil, "HEAD", do_link) + sources << "</div>\n<br>\n" sources << "<ul>" sources << " <li>#{history_add_line_label}</li>"