OSDN Git Service

8c00c4b2cca1f5e025c7ec78edecafcf178e6148
[fswiki/fswiki.git] / plugin / core / Diff.pm
1 ###############################################################################
2
3 # º¹Ê¬¤òɽ¼¨¤¹¤ë¥×¥é¥°¥¤¥ó
4
5 ###############################################################################
6 package plugin::core::Diff;
7 use Algorithm::Diff qw(traverse_sequences);
8 use strict;
9
10 #==============================================================================
11 # ¥³¥ó¥¹¥È¥é¥¯¥¿
12 #==============================================================================
13 sub new {
14         my $class = shift;
15         my $self = {};
16         
17         return bless $self,$class;
18 }
19
20 #==============================================================================
21 # ¥¢¥¯¥·¥ç¥ó¤Î¼Â¹Ô
22 #==============================================================================
23 sub do_action {
24         my $self = shift;
25         my $wiki = shift;
26         my $cgi = $wiki->get_CGI;
27         
28         my $pagename = $cgi->param("page");
29         if($pagename eq ""){
30                 $pagename = $wiki->config("frontpage");
31         }
32         unless($wiki->can_show($pagename)){
33                 return $wiki->error("»²¾È¸¢¸Â¤¬¤¢¤ê¤Þ¤»¤ó¡£");
34         }
35         if($cgi->param('rollback') ne ''){
36                 return $self->rollback($wiki, $pagename, $cgi->param('rollback'));
37         } elsif($wiki->{storage}->backup_type eq 'all'){
38                 if($cgi->param('generation') eq '' && $cgi->param('diff') eq ''){
39                         return $self->show_history($wiki, $pagename);
40                 } else {
41                         if($cgi->param('generation') ne ''){
42                                 return $self->show_diff($wiki, $pagename, '', $cgi->param('generation'));
43                         }
44                         return $self->show_diff($wiki, $pagename, $cgi->param('from'), $cgi->param('to'));
45                 }
46         } else {
47                 return $self->show_diff($wiki, $pagename, 0);
48         }
49 }
50
51 #==============================================================================
52 # ÍúÎò¤«¤é¥Ú¡¼¥¸¤òÉü¸µ
53 #==============================================================================
54 sub rollback {
55         my $self = shift;
56         my $wiki = shift;
57         my $page = shift;
58         my $gen  = shift;
59         unless($wiki->can_modify_page($page)){
60                 return $wiki->error("¹¹¿·¸¢¸Â¤¬¤¢¤ê¤Þ¤»¤ó¡£");
61         }
62         my $source = $wiki->get_backup($page,$gen);
63         $wiki->save_page($page, $source);
64         return $wiki->redirect($page);
65 }
66
67 #==============================================================================
68 # ÍúÎò¤Î°ìÍ÷¤òɽ¼¨
69 # ¥¹¥È¥ì¡¼¥¸¤Îbackup_type=all¤Î¤È¤­
70 #==============================================================================
71 sub show_history {
72         my $self = shift;
73         my $wiki = shift;
74         my $pagename = shift;
75         
76         $wiki->set_title($pagename."¤ÎÊѹ¹ÍúÎò");
77         my $buf   = "<form><ul>\n";
78         my $count = 0;
79         my @list  = $wiki->{storage}->get_backup_list($pagename);
80         foreach my $time (@list){
81                 $buf .= "<li>Rev.".($#list-$count + 1);
82                 if($count == 0){
83                         $buf .= "<input type=\"radio\" name=\"from\" value=\"\">".
84                                 "<input type=\"radio\" name=\"to\" value=\"\">";
85                 } else {
86                         $buf .= "<input type=\"radio\" name=\"from\" value=\"".($#list-$count)."\">".
87                                 "<input type=\"radio\" name=\"to\" value=\"".($#list-$count)."\">";
88                 }
89                 $buf .= "<a href=\"".$wiki->create_url({ action=>"DIFF",page=>$pagename,generation=>($#list-$count) })."\">".&Util::escapeHTML($time).
90                         "</a>¡¡<a href=\"".$wiki->create_url({ action=>"SOURCE",page=>$pagename,generation=>($#list-$count) })."\">¥½¡¼¥¹</a>".
91                         "</li>\n";
92                 $count++;
93         }
94         return $buf."</ul>".
95         "<input type=\"hidden\" name=\"page\" value=\"".Util::escapeHTML($pagename)."\">".
96         "<input type=\"hidden\" name=\"action\" value=\"DIFF\">".
97         "<input type=\"submit\" name=\"diff\" value=\"ÁªÂò¤·¤¿¥ê¥Ó¥¸¥ç¥ó´Ö¤Îº¹Ê¬¤òɽ¼¨\"></form>\n";
98 }
99
100 #==============================================================================
101 # º¹Ê¬¤òɽ¼¨
102 #==============================================================================
103 sub show_diff {
104         my $self     = shift;
105         my $wiki     = shift;
106         my $pagename = shift;
107         my $from     = shift;
108         my $to       = shift;
109         
110         $wiki->set_title($pagename."¤ÎÊѹ¹ÅÀ");
111         my ($diff, $rollback) = $self->get_diff_html($wiki,$pagename, $from, $to);
112         
113         my $buf = qq|
114                 <ul>
115                   <li>Äɲ䵤줿¹Ô¤Ï<ins class="diff">¤³¤Î¤è¤¦¤Ë</ins>ɽ¼¨¤µ¤ì¤Þ¤¹¡£</li>
116                   <li>ºï½ü¤µ¤ì¤¿¹Ô¤Ï<del class="diff">¤³¤Î¤è¤¦¤Ë</del>ɽ¼¨¤µ¤ì¤Þ¤¹¡£</li>
117                 </ul>
118                 <pre>$diff</pre>
119         |;
120         
121         if($wiki->can_modify_page($pagename) && $rollback && $wiki->get_CGI->param('diff') eq ''){
122                 $buf .= qq|
123                         <form action="@{[$wiki->create_url()]}" method="POST">
124                                 <input type="submit" value="¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤ËÌ᤹"/>
125                                 <input type="hidden" name="action" value="DIFF"/>
126                                 <input type="hidden" name="page" value="@{[Util::escapeHTML($pagename)]}"/>
127                                 <input type="hidden" name="rollback" value="@{[Util::escapeHTML($from)]}"/>
128                         </form>
129                 |;
130         }
131         
132         return $buf;
133 }
134
135 #==============================================================================
136 # º¹Ê¬Ê¸»úÎó¤ò¼èÆÀ
137 #==============================================================================
138 sub get_diff_text {
139         my $self       = shift;
140         my $wiki       = shift;
141         my $pagename   = shift;
142         my $generation = shift;
143         
144         my $source1 = $wiki->get_page($pagename);
145         my $source2 = $wiki->get_backup($pagename,$generation);
146         my $format  = $wiki->get_edit_format();
147         
148         $source1 = $wiki->convert_from_fswiki($source1,$format);
149         $source2 = $wiki->convert_from_fswiki($source2,$format);
150         
151         my $diff_text = "";
152         my @msg1 = split(/\n/,$source1);
153         my @msg2 = split(/\n/,$source2);
154         my $msgrefA = \@msg2;
155         my $msgrefB = \@msg1;
156         
157         traverse_sequences($msgrefA, $msgrefB,
158                 {
159                         MATCH => sub {},
160                         DISCARD_A => sub {
161                                 my ($a, $b) = @_;
162                                 $diff_text .= "-".$msgrefA->[$a]."\n";
163                         },
164                         DISCARD_B => sub {
165                                 my ($a, $b) = @_;
166                                 $diff_text .= "+".$msgrefB->[$b]."\n";
167                         }
168                 });
169         
170         return $diff_text;
171 }
172
173 #==============================================================================
174 # º¹Ê¬Ê¸»úÎó¤òɽ¼¨ÍÑHTML¤È¤·¤Æ¼èÆÀ
175 #==============================================================================
176 sub get_diff_html {
177         my $self     = shift;
178         my $wiki     = shift;
179         my $pagename = shift;
180         my $from     = shift;
181         my $to       = shift;
182         
183         my $source1 = '';
184         if($from ne ''){
185                 $source1 = $wiki->get_backup($pagename, $from);
186         } else {
187                 $source1 = $wiki->get_page($pagename);
188         }
189         my $source2 = '';
190         if($to ne ''){
191                 $source2 = $wiki->get_backup($pagename, $to);
192         } else {
193                 $source2 = $wiki->get_page($pagename);
194         }
195         my $format  = $wiki->get_edit_format();
196         
197         $source1 = $wiki->convert_from_fswiki($source1, $format);
198         $source2 = $wiki->convert_from_fswiki($source2, $format);
199         
200         my $diff_text = "";
201         my @msg1 = split(/\n/,$source1);
202         return "¥Ú¡¼¥¸¤¬Â礭¤¹¤®¤ë¤¿¤áº¹Ê¬¤òɽ¼¨¤Ç¤­¤Þ¤»¤ó¡£" if($#msg1 >= 999);
203         my @msg2 = split(/\n/,$source2);
204         return "¥Ú¡¼¥¸¤¬Â礭¤¹¤®¤ë¤¿¤áº¹Ê¬¤òɽ¼¨¤Ç¤­¤Þ¤»¤ó¡£" if($#msg2 >= 999);
205         my $msgrefA = \@msg2;
206         my $msgrefB = \@msg1;
207         
208         traverse_sequences($msgrefA, $msgrefB,
209                 {
210                         MATCH => sub {
211                                 my ($a, $b) = @_;
212                                 $diff_text .= Util::escapeHTML($msgrefA->[$a])."\n";
213                         },
214                         DISCARD_A => sub {
215                                 my ($a, $b) = @_;
216                                 $diff_text .= "<del class=\"diff\">".Util::escapeHTML($msgrefA->[$a])."</del>\n";
217                         },
218                         DISCARD_B => sub {
219                                 my ($a, $b) = @_;
220                                 $diff_text .= "<ins class=\"diff\">".Util::escapeHTML($msgrefB->[$b])."</ins>\n";
221                         }
222                 });
223         
224         return ($diff_text, $source2 ne "");
225 }
226
227 #==============================================================================
228 # ¥Ú¡¼¥¸É½¼¨»þ¤Î¥Õ¥Ã¥¯¥á¥½¥Ã¥É
229 # ¡Öº¹Ê¬¡×¥á¥Ë¥å¡¼¤òÍ­¸ú¤Ë¤·¤Þ¤¹
230 #==============================================================================
231 sub hook {
232         my $self = shift;
233         my $wiki = shift;
234         my $cgi  = $wiki->get_CGI;
235         
236         my $pagename = $cgi->param("page");
237         $wiki->add_menu("º¹Ê¬",$wiki->create_url({ action=>"DIFF",page=>$pagename }));
238 }
239
240 1;