[Hiki-dev:00652] 編集履歴のインターフェイスをよりリッチに

アーカイブの一覧に戻る

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>"


Hiki-dev メーリングリストの案内
アーカイブの一覧に戻る