summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2008-11-15 11:51:58 +0100
committerYorhel <git@yorhel.nl>2008-11-15 11:51:58 +0100
commitdb820616d0f5c7f49e725987b6cd900944e4ffd0 (patch)
tree1c1763eaf527a70b84b5a67a0ba6ccc32ef6ff93 /lib
parentdbaba80b10273270a16e91118fa12e081d4707f7 (diff)
Wrote revision and diff viewer
Character-level diffs instead of the old word-level diffs. Still only works on plaintext, though. Not really sure about the style, either.
Diffstat (limited to 'lib')
-rw-r--r--lib/ChangeLog2
-rw-r--r--lib/VNDB/Func.pm8
-rw-r--r--lib/VNDB/Handler/Producers.pm18
-rw-r--r--lib/VNDB/Util/CommonHTML.pm118
4 files changed, 140 insertions, 6 deletions
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 2dde0f6a..167bb9e4 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -20,6 +20,8 @@ TODO:
- Functionality changes:
- Ability to sort the userlist on vote and change counts
- Added threads and posts counts to the global statistics
+ - Improved diff calculation
+ - Whitespace around input fields are removed
1.23 - 2008-10-22 (r117)
- Removed redirects for old revision URLs (the code wasn't very secure...)
diff --git a/lib/VNDB/Func.pm b/lib/VNDB/Func.pm
index bc6cbc87..ef18c837 100644
--- a/lib/VNDB/Func.pm
+++ b/lib/VNDB/Func.pm
@@ -15,11 +15,13 @@ sub shorten {
}
-# argument: unix timestamp
+# argument: unix timestamp and optional format (compact/full)
# return value: yyyy-mm-dd
# (maybe an idea to use cgit-style ages for recent timestamps)
sub date {
- return strftime '%Y-%m-%d', gmtime shift;
+ my($t, $f) = @_;
+ return strftime '%Y-%m-%d', gmtime $t if !$f || $f eq 'compact';
+ return strftime '%Y-%m-%d at %R', gmtime $t;
}
@@ -56,7 +58,7 @@ sub bb2html {
my $raw = shift;
my $maxlength = shift;
$raw =~ s/\r//g;
- return '' if !$raw && $raw != 0;
+ return '' if !$raw && $raw ne "0";
my($result, $length, @open) = ('', 0, 'first');
diff --git a/lib/VNDB/Handler/Producers.pm b/lib/VNDB/Handler/Producers.pm
index 43588031..bacabb08 100644
--- a/lib/VNDB/Handler/Producers.pm
+++ b/lib/VNDB/Handler/Producers.pm
@@ -18,12 +18,28 @@ YAWF::register(
sub page {
my($self, $pid, $rev) = @_;
- my $p = $self->dbProducerGet(id => $pid, what => 'vn')->[0];
+ my $p = $self->dbProducerGet(
+ id => $pid,
+ what => 'vn'.($rev ? ' changes' : ''),
+ $rev ? ( rev => $rev ) : ()
+ )->[0];
return 404 if !$p->{id};
$self->htmlHeader(title => $p->{name});
$self->htmlMainTabs(p => $p);
+ if($rev) {
+ my $prev = $rev && $rev > 1 && $self->dbProducerGet(id => $pid, rev => $rev-1, what => 'changes')->[0];
+ $self->htmlRevision('p', $prev, $p,
+ [ type => 'Type', serialize => sub { $self->{producer_types}{$_[0]} } ],
+ [ name => 'Name (romaji)', diff => 1 ],
+ [ original => 'Original name', diff => 1 ],
+ [ lang => 'Language', serialize => sub { "$_[0] ($self->{languages}{$_[0]})" } ],
+ [ website => 'Website', diff => 1 ],
+ [ desc => 'Description', diff => 1 ],
+ );
+ }
+
if($p->{hidden}) {
div class => 'mainbox';
h1 $p->{name};
diff --git a/lib/VNDB/Util/CommonHTML.pm b/lib/VNDB/Util/CommonHTML.pm
index f2c4d6ff..25e25982 100644
--- a/lib/VNDB/Util/CommonHTML.pm
+++ b/lib/VNDB/Util/CommonHTML.pm
@@ -3,10 +3,12 @@ package VNDB::Util::CommonHTML;
use strict;
use warnings;
-use YAWF ':html';
+use YAWF ':html', 'xml_escape';
use Exporter 'import';
+use Algorithm::Diff 'sdiff';
+use VNDB::Func;
-our @EXPORT = qw|htmlMainTabs htmlDenied htmlBrowse htmlBrowseNavigate|;
+our @EXPORT = qw|htmlMainTabs htmlDenied htmlBrowse htmlBrowseNavigate htmlRevision|;
# generates the "main tabs". These are the commonly used tabs for
@@ -178,4 +180,116 @@ sub htmlBrowseNavigate {
}
+# Shows a revision, including diff if there is a previous revision.
+# Arguments: v|p|r, old revision, new revision, @fields
+# Where @fields is a list of fields as arrayrefs with:
+# [ shortname, displayname, %options ],
+# Where %options:
+# diff => 1/0, whether do show a diff on this field
+# serialize => coderef, should convert the field into a readable string, no HTML allowed
+sub htmlRevision {
+ my($self, $type, $old, $new, @fields) = @_;
+ div class => 'mainbox revision';
+ h1 'Revision '.$new->{rev};
+
+ # previous/next revision links
+ a class => 'prev', href => sprintf('/%s%d.%d', $type, $new->{id}, $new->{rev}-1), '<- earlier revision'
+ if $new->{rev} > 1;
+ a class => 'next', href => sprintf('/%s%d.%d', $type, $new->{id}, $new->{rev}+1), 'later revision ->'
+ if $new->{cid} != $new->{latest};
+ p class => 'center';
+ a href => "/$type$new->{id}", "$type$new->{id}";
+ end;
+
+ # no previous revision, just show info about the revision itself
+ if(!$old) {
+ div;
+ revheader($type, $new);
+ br;
+ b 'Edit summary:';
+ br; br;
+ lit bb2html($new->{comments})||'[no summary]';
+ end;
+ }
+
+ # otherwise, compare the two revisions
+ else {
+ table;
+ thead;
+ Tr;
+ td; lit '&nbsp;'; end;
+ td; revheader($type, $old); end;
+ td; revheader($type, $new); end;
+ end;
+ Tr;
+ td; lit '&nbsp;'; end;
+ td colspan => 2;
+ b 'Edit summary of revision '.$new->{rev}.':';
+ br; br;
+ lit bb2html($new->{comments})||'[no summary]';
+ end;
+ end;
+ end;
+ my $i = 1;
+ revdiff(\$i, $old, $new, @$_) for (@fields);
+ end;
+ }
+ end;
+}
+
+sub revheader { # type, obj
+ my($type, $obj) = @_;
+ b 'Revision '.$obj->{rev};
+ txt ' (';
+ a href => "/$type$obj->{id}?rev=1", 'edit';
+ txt ')';
+ br;
+ txt 'By ';
+ a href => "/u$obj->{requester}", $obj->{username};
+ txt ' on ';
+ lit date $obj->{added}, 'full';
+}
+
+sub revdiff {
+ my($i, $old, $new, $short, $name, %o) = @_;
+
+ my $ser1 = $o{serialize} ? $o{serialize}->($old->{$short}) : $old->{$short};
+ my $ser2 = $o{serialize} ? $o{serialize}->($new->{$short}) : $new->{$short};
+ return if $ser1 eq $ser2;
+
+ if($o{diff} && $ser1 && $ser2) {
+ my($r1,$r2,$ch) = ('','','u');
+ for (sdiff([ split //, $ser1 ], [ split //, $ser2 ])) {
+ if($ch ne $_->[0]) {
+ if($ch ne 'u') {
+ $r1 .= '</b>';
+ $r2 .= '</b>';
+ }
+ $r1 .= '<b class="diff_del">' if $_->[0] eq '-' || $_->[0] eq 'c';
+ $r2 .= '<b class="diff_add">' if $_->[0] eq '+' || $_->[0] eq 'c';
+ }
+ $ch = $_->[0];
+ $r1 .= xml_escape $_->[1] if $ch ne '+';
+ $r2 .= xml_escape $_->[2] if $ch ne '-';
+ }
+ $r1 .= '</b>' if $ch eq '-' || $ch eq 'c';
+ $r2 .= '</b>' if $ch eq '+' || $ch eq 'c';
+ $ser1 = $r1;
+ $ser2 = $r2;
+ } else {
+ $ser1 = xml_escape $ser1;
+ $ser2 = xml_escape $ser2;
+ }
+
+ $ser1 = '[empty]' if !$ser1 && $ser1 ne '0';
+ $ser2 = '[empty]' if !$ser2 && $ser2 ne '0';
+
+ Tr $$i++ % 2 ? (class => 'odd') : ();
+ td class => 'tcname', $name;
+ td; lit $ser1; end;
+ td; lit $ser2; end;
+ end;
+}
+
+
1;