OSDN Git Service

コンフリクト時に差分を表示するようにした。
[fswiki/fswiki.git] / plugin / core / Diff.pm
index 9889b60..c3faea3 100644 (file)
-###############################################################################\r
-# \r
-# º¹Ê¬¤òɽ¼¨¤¹¤ë¥×¥é¥°¥¤¥ó\r
-# \r
-###############################################################################\r
-package plugin::core::Diff;\r
-use Algorithm::Diff qw(traverse_sequences);\r
-use strict;\r
+###############################################################################
+# 
+# º¹Ê¬¤òɽ¼¨¤¹¤ë¥×¥é¥°¥¤¥ó
+# 
+###############################################################################
+package plugin::core::Diff;
+use Algorithm::Diff qw(traverse_sequences);
+use strict;
+
+#==============================================================================
+# ¥³¥ó¥¹¥È¥é¥¯¥¿
+#==============================================================================
+sub new {
+       my $class = shift;
+       my $self = {};
+       
+       return bless $self,$class;
+}
+
+#==============================================================================
+# ¥¢¥¯¥·¥ç¥ó¤Î¼Â¹Ô
+#==============================================================================
+sub do_action {
+       my $self = shift;
+       my $wiki = shift;
+       my $cgi = $wiki->get_CGI;
+       
+       my $pagename = $cgi->param("page");
+       if($pagename eq ""){
+               $pagename = $wiki->config("frontpage");
+       }
+       unless($wiki->can_show($pagename)){
+               return $wiki->error("»²¾È¸¢¸Â¤¬¤¢¤ê¤Þ¤»¤ó¡£");
+       }
+       if($cgi->param('rollback') ne ''){
+               return $self->rollback($wiki, $pagename, $cgi->param('rollback'));
+       } elsif($wiki->{storage}->backup_type eq 'all'){
+               if($cgi->param('generation') eq '' && $cgi->param('diff') eq ''){
+                       return $self->show_history($wiki, $pagename);
+               } else {
+                       if($cgi->param('generation') ne ''){
+                               return $self->show_diff($wiki, $pagename, '', $cgi->param('generation'));
+                       }
+                       return $self->show_diff($wiki, $pagename, $cgi->param('from'), $cgi->param('to'));
+               }
+       } else {
+               return $self->show_diff($wiki, $pagename, '', 0);
+       }
+}
+
+#==============================================================================
+# ÍúÎò¤«¤é¥Ú¡¼¥¸¤òÉü¸µ
+#==============================================================================
+sub rollback {
+       my $self = shift;
+       my $wiki = shift;
+       my $page = shift;
+       my $gen  = shift;
+       unless($wiki->can_modify_page($page)){
+               return $wiki->error("¹¹¿·¸¢¸Â¤¬¤¢¤ê¤Þ¤»¤ó¡£");
+       }
+       my $source = $wiki->get_backup($page,$gen);
+       $wiki->save_page($page, $source);
+       return $wiki->redirect($page);
+}
+
+#==============================================================================
+# ÍúÎò¤Î°ìÍ÷¤òɽ¼¨
+# ¥¹¥È¥ì¡¼¥¸¤Îbackup_type=all¤Î¤È¤­
+#==============================================================================
+sub show_history {
+       my $self = shift;
+       my $wiki = shift;
+       my $page = shift;
+       
+       $wiki->set_title("$page¤ÎÊѹ¹ÍúÎò");
+       my $buf   = "<form><ul>\n";
+       my $count = 0;
+       my @list  = $wiki->{storage}->get_backup_list($page);
+       
+       if($#list == -1){
+               return "ÍúÎò¤Ï¤¢¤ê¤Þ¤»¤ó¡£";
+       }
+       
+       # editlog¥×¥é¥°¥¤¥ó¤Î¥í¥°¤«¤éÊÔ½¸¼Ô¤Î¥æ¡¼¥¶Ì¾¤ò¼èÆÀ
+       my $editlog = {};
+       if($wiki->config('log_dir') ne "" && -e $wiki->config('log_dir')."/useredit.log"){
+               open(DATA,$wiki->config('log_dir')."/useredit.log") or die $!;
+               while(<DATA>){
+                       my($date, $time, $unixtime, $action, $subject, $id) = split(" ",$_);
+                       if($subject eq $page){
+                               if($id eq ''){
+                                       $editlog->{$unixtime} = 'anonymous';
+                               } else {
+                                       $editlog->{$unixtime} = $id;
+                               }
+                       }
+               }
+               close(DATA);
+       }
+       
+       foreach my $time (@list){
+               $buf .= "<li>";
+               if($count == 0){
+                       $buf .= "<input type=\"radio\" name=\"from\" value=\"\" checked>".
+                               "<input type=\"radio\" name=\"to\" value=\"\" checked>";
+               } else {
+                       $buf .= "<input type=\"radio\" name=\"from\" value=\"".($#list-$count+1)."\">".
+                               "<input type=\"radio\" name=\"to\" value=\"".($#list-$count+1)."\">";
+               }
+               $buf .= "<a href=\"".$wiki->create_url({ action=>"DIFF",page=>$page,generation=>($#list-$count) })."\">".&Util::format_date($time).
+                       "</a> <a href=\"".$wiki->create_url({ action=>"SOURCE",page=>$page,generation=>($#list-$count) })."\">¥½¡¼¥¹</a>";
+                       
+               if(defined($editlog->{$time})){
+                       $buf .= " by ".$editlog->{$time};
+               }
+               
+               $buf .=  "</li>\n";
+               $count++;
+       }
+       return $buf."</ul>".
+       "<input type=\"hidden\" name=\"page\" value=\"".Util::escapeHTML($page)."\">".
+       "<input type=\"hidden\" name=\"action\" value=\"DIFF\">".
+       "<input type=\"submit\" name=\"diff\" value=\"ÁªÂò¤·¤¿¥ê¥Ó¥¸¥ç¥ó´Ö¤Îº¹Ê¬¤òɽ¼¨\"></form>\n";
+}
+
+#==============================================================================
+# º¹Ê¬¤òɽ¼¨
+#==============================================================================
+sub show_diff {
+       my $self = shift;
+       my $wiki = shift;
+       my $page = shift;
+       my $from = shift;
+       my $to   = shift;
+       
+       $wiki->set_title("$page¤ÎÊѹ¹ÅÀ");
+       my ($diff, $rollback) = $self->get_diff_html($wiki,$page, $from, $to);
+       
+       $diff =~ s/\n/<br>/g;
+       
+       my $buf = qq|
+               <ul>
+                 <li>Äɲ䵤줿Éôʬ¤Ï<ins class="diff">¤³¤Î¤è¤¦¤Ë</ins>ɽ¼¨¤µ¤ì¤Þ¤¹¡£</li>
+                 <li>ºï½ü¤µ¤ì¤¿Éôʬ¤Ï<del class="diff">¤³¤Î¤è¤¦¤Ë</del>ɽ¼¨¤µ¤ì¤Þ¤¹¡£</li>
+               </ul>
+               <div class="diff">$diff</div>
+       |;
+       
+       if($wiki->can_modify_page($page) && $rollback && $wiki->get_CGI->param('diff') eq ''){
+               $buf .= qq|
+                       <form action="@{[$wiki->create_url()]}" method="POST">
+                               <input type="submit" value="¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤ËÌ᤹"/>
+                               <input type="hidden" name="action" value="DIFF"/>
+                               <input type="hidden" name="page" value="@{[Util::escapeHTML($page)]}"/>
+                               <input type="hidden" name="rollback" value="@{[Util::escapeHTML($from)]}"/>
+                       </form>
+               |;
+       }
+       
+       return $buf;
+}
+
+#==============================================================================
+# º¹Ê¬Ê¸»úÎó¤ò¼èÆÀ
+#==============================================================================
+sub get_diff_text {
+       my $self = shift;
+       my $wiki = shift;
+       my $page = shift;
+       my $gen  = shift;
+       
+       my $source1 = $wiki->get_page($page);
+       my $source2 = $wiki->get_backup($page, $gen);
+       my $format  = $wiki->get_edit_format();
+       
+       $source1 = $wiki->convert_from_fswiki($source1, $format);
+       $source2 = $wiki->convert_from_fswiki($source2, $format);
+       
+       my $diff_text = "";
+       my @msg1 = split(/\n/,$source1);
+       my @msg2 = split(/\n/,$source2);
+       my $msgrefA = \@msg2;
+       my $msgrefB = \@msg1;
+       
+       traverse_sequences($msgrefA, $msgrefB,
+               {
+                       MATCH => sub {},
+                       DISCARD_A => sub {
+                               my ($a, $b) = @_;
+                               $diff_text .= "-".$msgrefA->[$a]."\n";
+                       },
+                       DISCARD_B => sub {
+                               my ($a, $b) = @_;
+                               $diff_text .= "+".$msgrefB->[$b]."\n";
+                       }
+               });
+       
+       return $diff_text;
+}
+
+#==============================================================================
+# º¹Ê¬Ê¸»úÎó¤òɽ¼¨ÍÑHTML¤È¤·¤Æ¼èÆÀ
+#==============================================================================
+sub get_diff_html {
+       my $self = shift;
+       my $wiki = shift;
+       my $page = shift;
+       my $from = shift;
+       my $to   = shift;
+       
+       my $source1 = '';
+       if($from ne ''){
+               $source1 = $wiki->get_backup($page, $from);
+       } else {
+               $source1 = $wiki->get_page($page);
+       }
+       my $source2 = '';
+       if($to ne ''){
+               $source2 = $wiki->get_backup($page, $to);
+       } else {
+               $source2 = $wiki->get_page($page);
+       }
+       my $format  = $wiki->get_edit_format();
+       
+       $source1 = $wiki->convert_from_fswiki($source1, $format);
+       $source2 = $wiki->convert_from_fswiki($source2, $format);
+       
+       return (&_get_diff_html($source1, $source2), $source2 ne "");
+}
+
+#==============================================================================
+# º¹Ê¬HTML¤òÀ¸À®¤¹¤ë´Ø¿ô
+#==============================================================================
+sub _get_diff_html {
+       my $self = shift;
+       my $source1 = shift;
+       my $source2 = shift;
+       
+       my @msg1 = _str_jfold($source1, 1);
+       my @msg2 = _str_jfold($source2, 1);
+       
+       my $msgrefA = \@msg2;
+       my $msgrefB = \@msg1;
+       
+       my $diff_text = "";
+       
+       traverse_sequences($msgrefA, $msgrefB,
+               {
+                       MATCH => sub {
+                               my ($a, $b) = @_;
+                               $diff_text .= Util::escapeHTML($msgrefA->[$a]);
+                       },
+                       DISCARD_A => sub {
+                               my ($a, $b) = @_;
+                               $diff_text .= "<del class=\"diff\">".Util::escapeHTML($msgrefA->[$a])."</del><wbr>";
+                       },
+                       DISCARD_B => sub {
+                               my ($a, $b) = @_;
+                               $diff_text .= "<ins class=\"diff\">".Util::escapeHTML($msgrefB->[$b])."</ins><wbr>";
+                       }
+               });
+       
+       return $diff_text;
+}
+
+#==============================================================================
+# Ê¸»úÎó¤ò»ØÄêʸ»ú¿ô¤òʬ³ä
+#==============================================================================
+sub _str_jfold {\r
+  my $str    = shift;       #»ØÄêʸ»úÎó\r
+  my $byte   = shift;       #»ØÄê¥Ð¥¤¥È\r
+  my $j      = new Jcode($str);\r
+  my @result = ();\r
 \r
-#==============================================================================\r
-# ¥³¥ó¥¹¥È¥é¥¯¥¿\r
-#==============================================================================\r
-sub new {\r
-       my $class = shift;\r
-       my $self = {};\r
-       \r
-       return bless $self,$class;\r
-}\r
+  foreach my $buff ( $j->jfold($byte) ){\r
+    push(@result, $buff);\r
+  }\r
 \r
-#==============================================================================\r
-# ¥¢¥¯¥·¥ç¥ó¤Î¼Â¹Ô\r
-#==============================================================================\r
-sub do_action {\r
-       my $self = shift;\r
-       my $wiki = shift;\r
-       my $cgi = $wiki->get_CGI;\r
-       \r
-       my $pagename = $cgi->param("page");\r
-       if($pagename eq ""){\r
-               $pagename = $wiki->config("frontpage");\r
-       }\r
-       unless($wiki->can_show($pagename)){\r
-               return $wiki->error("»²¾È¸¢¸Â¤¬¤¢¤ê¤Þ¤»¤ó¡£");\r
-       }\r
-       if($cgi->param('rollback') ne ''){\r
-               return $self->rollback($wiki, $pagename, $cgi->param('rollback'));\r
-       } elsif($wiki->{storage}->backup_type eq "all"){\r
-               if($cgi->param("generation") eq ""){\r
-                       return $self->show_history($wiki,$pagename);\r
-               } else {\r
-                       return $self->show_diff($wiki,$pagename,$cgi->param("generation"));\r
-               }\r
-       } else {\r
-               return $self->show_diff($wiki,$pagename,0);\r
-       }\r
-}\r
-\r
-#==============================================================================\r
-# ÍúÎò¤«¤é¥Ú¡¼¥¸¤òÉü¸µ\r
-#==============================================================================\r
-sub rollback {\r
-       my $self = shift;\r
-       my $wiki = shift;\r
-       my $page = shift;\r
-       my $gen  = shift;\r
-       unless($wiki->can_modify_page($page)){\r
-               return $wiki->error("¹¹¿·¸¢¸Â¤¬¤¢¤ê¤Þ¤»¤ó¡£");\r
-       }\r
-       my $source = $wiki->get_backup($page,$gen);\r
-       $wiki->save_page($page, $source);\r
-       return $wiki->redirect($page);\r
-}\r
-\r
-#==============================================================================\r
-# ÍúÎò¤Î°ìÍ÷¤òɽ¼¨\r
-# ¥¹¥È¥ì¡¼¥¸¤Îbackup_type=all¤Î¤È¤­\r
-#==============================================================================\r
-sub show_history {\r
-       my $self = shift;\r
-       my $wiki = shift;\r
-       my $pagename = shift;\r
-       \r
-       $wiki->set_title($pagename."¤ÎÊѹ¹ÍúÎò");\r
-       my $buf   = "<ul>\n";\r
-       my $count = 0;\r
-       my @list  = $wiki->{storage}->get_backup_list($pagename);\r
-       foreach my $time (@list){\r
-               $buf .= "<li><a href=\"".$wiki->create_url({ action=>"DIFF",page=>$pagename,generation=>($#list-$count) })."\">".&Util::escapeHTML($time).\r
-                       "</a>¡¡<a href=\"".$wiki->create_url({ action=>"SOURCE",page=>$pagename,generation=>($#list-$count) })."\">¥½¡¼¥¹</a>".\r
-                       "</li>\n";\r
-               $count++;\r
-       }\r
-       return $buf."</ul>\n";\r
-}\r
-\r
-#==============================================================================\r
-# º¹Ê¬¤òɽ¼¨\r
-#==============================================================================\r
-sub show_diff {\r
-       my $self       = shift;\r
-       my $wiki       = shift;\r
-       my $pagename   = shift;\r
-       my $generation = shift;\r
-       \r
-       $wiki->set_title($pagename."¤ÎÊѹ¹ÅÀ");\r
-       my ($diff, $rollback) = $self->get_diff_html($wiki,$pagename,$generation);\r
-       \r
-       my $buf = qq|\r
-               <ul>\r
-                 <li>Äɲ䵤줿¹Ô¤Ï<ins class="diff">¤³¤Î¤è¤¦¤Ë</ins>ɽ¼¨¤µ¤ì¤Þ¤¹¡£</li>\r
-                 <li>ºï½ü¤µ¤ì¤¿¹Ô¤Ï<del class="diff">¤³¤Î¤è¤¦¤Ë</del>ɽ¼¨¤µ¤ì¤Þ¤¹¡£</li>\r
-               </ul>\r
-               <pre>$diff</pre>\r
-       |;\r
-       \r
-       if($wiki->can_modify_page($pagename) && $rollback){\r
-               $buf .= qq|\r
-                       <form action="@{[$wiki->create_url()]}" method="POST">\r
-                               <input type="submit" value="¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤ËÌ᤹"/>\r
-                               <input type="hidden" name="action" value="DIFF"/>\r
-                               <input type="hidden" name="page" value="@{[Util::escapeHTML($pagename)]}"/>\r
-                               <input type="hidden" name="rollback" value="@{[Util::escapeHTML($generation)]}"/>\r
-                       </form>\r
-               |;\r
-       }\r
-       \r
-       return $buf;\r
-}\r
-\r
-#==============================================================================\r
-# º¹Ê¬Ê¸»úÎó¤ò¼èÆÀ\r
-#==============================================================================\r
-sub get_diff_text {\r
-       my $self       = shift;\r
-       my $wiki       = shift;\r
-       my $pagename   = shift;\r
-       my $generation = shift;\r
-       \r
-       my $source1 = $wiki->get_page($pagename);\r
-       my $source2 = $wiki->get_backup($pagename,$generation);\r
-       my $format  = $wiki->get_edit_format();\r
-       \r
-       $source1 = $wiki->convert_from_fswiki($source1,$format);\r
-       $source2 = $wiki->convert_from_fswiki($source2,$format);\r
-       \r
-       my $diff_text = "";\r
-       my @msg1 = split(/\n/,$source1);\r
-       my @msg2 = split(/\n/,$source2);\r
-       my $msgrefA = \@msg2;\r
-       my $msgrefB = \@msg1;\r
-       \r
-       traverse_sequences($msgrefA, $msgrefB,\r
-               {\r
-                       MATCH => sub {},\r
-                       DISCARD_A => sub {\r
-                               my ($a, $b) = @_;\r
-                               $diff_text .= "-".$msgrefA->[$a]."\n";\r
-                       },\r
-                       DISCARD_B => sub {\r
-                               my ($a, $b) = @_;\r
-                               $diff_text .= "+".$msgrefB->[$b]."\n";\r
-                       }\r
-               });\r
-       \r
-       return $diff_text;\r
-}\r
-\r
-#==============================================================================\r
-# º¹Ê¬Ê¸»úÎó¤òɽ¼¨ÍÑHTML¤È¤·¤Æ¼èÆÀ\r
-#==============================================================================\r
-sub get_diff_html {\r
-       my $self       = shift;\r
-       my $wiki       = shift;\r
-       my $pagename   = shift;\r
-       my $generation = shift;\r
-       \r
-       my $source1 = $wiki->get_page($pagename);\r
-       my $source2 = $wiki->get_backup($pagename,$generation);\r
-       my $format  = $wiki->get_edit_format();\r
-       \r
-       $source1 = $wiki->convert_from_fswiki($source1,$format);\r
-       $source2 = $wiki->convert_from_fswiki($source2,$format);\r
-       \r
-       my $diff_text = "";\r
-       my @msg1 = split(/\n/,$source1);\r
-       return "¥Ú¡¼¥¸¤¬Â礭¤¹¤®¤ë¤¿¤áº¹Ê¬¤òɽ¼¨¤Ç¤­¤Þ¤»¤ó¡£" if($#msg1 >= 999);\r
-       my @msg2 = split(/\n/,$source2);\r
-       return "¥Ú¡¼¥¸¤¬Â礭¤¹¤®¤ë¤¿¤áº¹Ê¬¤òɽ¼¨¤Ç¤­¤Þ¤»¤ó¡£" if($#msg2 >= 999);\r
-       my $msgrefA = \@msg2;\r
-       my $msgrefB = \@msg1;\r
-       \r
-       traverse_sequences($msgrefA, $msgrefB,\r
-               {\r
-                       MATCH => sub {\r
-                               my ($a, $b) = @_;\r
-                               $diff_text .= Util::escapeHTML($msgrefA->[$a])."\n";\r
-                       },\r
-                       DISCARD_A => sub {\r
-                               my ($a, $b) = @_;\r
-                               $diff_text .= "<del class=\"diff\">".Util::escapeHTML($msgrefA->[$a])."</del>\n";\r
-                       },\r
-                       DISCARD_B => sub {\r
-                               my ($a, $b) = @_;\r
-                               $diff_text .= "<ins class=\"diff\">".Util::escapeHTML($msgrefB->[$b])."</ins>\n";\r
-                       }\r
-               });\r
-       \r
-       return ($diff_text, $source2 ne "");\r
-}\r
-\r
-#==============================================================================\r
-# ¥Ú¡¼¥¸É½¼¨»þ¤Î¥Õ¥Ã¥¯¥á¥½¥Ã¥É\r
-# ¡Öº¹Ê¬¡×¥á¥Ë¥å¡¼¤òÍ­¸ú¤Ë¤·¤Þ¤¹\r
-#==============================================================================\r
-sub hook {\r
-       my $self = shift;\r
-       my $wiki = shift;\r
-       my $cgi  = $wiki->get_CGI;\r
-       \r
-       my $pagename = $cgi->param("page");\r
-       $wiki->add_menu("º¹Ê¬",$wiki->create_url({ action=>"DIFF",page=>$pagename }));\r
-}\r
-\r
-1;\r
+  return(@result);\r
+}
+
+#==============================================================================
+# ¥Ú¡¼¥¸É½¼¨»þ¤Î¥Õ¥Ã¥¯¥á¥½¥Ã¥É
+# ¡Öº¹Ê¬¡×¥á¥Ë¥å¡¼¤òÍ­¸ú¤Ë¤·¤Þ¤¹
+#==============================================================================
+sub hook {
+       my $self = shift;
+       my $wiki = shift;
+       my $cgi  = $wiki->get_CGI;
+       my $page = $cgi->param("page");
+       if($wiki->{storage}->backup_type eq 'all'){
+               $wiki->add_menu("ÍúÎò",$wiki->create_url({ action=>"DIFF",page=>$page }));
+       } else {
+               $wiki->add_menu("º¹Ê¬",$wiki->create_url({ action=>"DIFF",page=>$page }));
+       }
+}
+
+1;