User: sits
Date: 08/03/09 12:57:09
Modified: lib/Codestriker/Action ViewTopic.pm
lib/Codestriker/Http UrlBuilder.pm
template/en/default viewtopic.html.tmpl
Added: lib/Codestriker/Http DeltaRenderer.pm
template/en/default viewdeltas.html.tmpl
Log:
A lot of stuff for the view topic page has been moved to templates. Still
a bit of work to be done to complete this, but a lot has been done. Still
need to move the text manipulation code into separate filter classes, so
that syntax highlighting will be easier to add in.
Index: ViewTopic.pm
===================================================================
RCS file:
/cvsroot/codestriker/codestriker/lib/Codestriker/Action/ViewTopic.pm,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- ViewTopic.pm 28 Feb 2008 11:01:58 -0000 1.54
+++ ViewTopic.pm 9 Mar 2008 19:57:07 -0000 1.55
@@ -11,10 +11,13 @@
use strict;
+use HTML::Entities ();
+
use Codestriker::Model::Topic;
use Codestriker::Model::Comment;
use Codestriker::Http::UrlBuilder;
use Codestriker::Http::Render;
+use Codestriker::Http::DeltaRenderer;
use Codestriker::Repository::RepositoryFactory;
use Codestriker::TopicListeners::Manager;
@@ -227,29 +230,78 @@
}
$vars->{'filetable'} = [EMAIL PROTECTED];
- # Pass in existing comment information.
- # Build a hash from filenumber|fileline|new -> comment array, so that
- # when rendering, lines can be coloured appropriately. Also build a list
- # of what points in the review have a comment. Also record a mapping
- # from filenumber|fileline|new -> the comment number.
- my %comment_hash = ();
- my @comment_locations = ();
- my %comment_location_map = ();
- for (my $i = 0; $i <= $#comments; $i++) {
- my $comment = $comments[$i];
- my $key = $comment->{filenumber} . "|" . $comment->{fileline} . "|" .
- $comment->{filenew};
- if (! exists $comment_hash{$key}) {
- push @comment_locations, $key;
- $comment_location_map{$key} = $#comment_locations;
+ # Determine which deltas are to be retrieved.
+ my @deltas = ();
+ if ($fview != -1) {
+ # Get only the deltas for the selected file.
+ @deltas = Codestriker::Model::Delta->get_delta_set($topicid, $fview);
+ }
+ else {
+ # Get the whole delta data.
+ @deltas = Codestriker::Model::Delta->get_delta_set($topicid, -1);
+ }
+
+ my $delta_renderer =
+ Codestriker::Http::Delta->new($topic, [EMAIL PROTECTED], [EMAIL
PROTECTED], $query,
+ $mode, $brmode);
+
+ # Set the add general comment URL.
+ $vars->{'add_general_comment_element'} =
+ $delta_renderer->comment_link(-1, -1, 1, "Add General Comment");
+
+ # Set the per-delta URL links, such as adding a file-level comment,
+ # and links to the previous/next file.
+ my $filenumber = 0;
+ my $current_filename = "";
+ foreach my $delta (@deltas) {
+ $delta->{add_file_comment_element} =
+ $delta_renderer->comment_link($filenumber, -1, 1, "[Add File
Comment]");
+
+ # Determine if the file has a link to a repository system,
+ # and if so, create the appropriate links.
+ if ($delta->{repmatch} &&
+ $delta->{revision} ne $Codestriker::ADDED_REVISION &&
+ $delta->{revision} ne $Codestriker::PATCH_REVISION &&
+ defined $repository) {
+ $delta->{repository_file_view_url} =
+ $repository->getViewUrl($delta->{filename});
+ $delta->{view_old_full_url} =
+ $url_builder->view_file_url($topicid, $filenumber, 0,
$delta->{old_linenumber},
+ $mode, 0);
+ $delta->{view_old_both_full_url} =
+ $url_builder->view_file_url($topicid, $filenumber, 0,
$delta->{old_linenumber},
+ $mode, 1);
+ $delta->{view_new_full_url} =
+ $url_builder->view_file_url($topicid, $filenumber, 1,
$delta->{new_linenumber},
+ $mode, 0);
+ $delta->{view_new_both_full_url} =
+ $url_builder->view_file_url($topicid, $filenumber, 1,
$delta->{new_linenumber},
+ $mode, 1);
+ }
+
+ # Create the next/previous file URL links.
+ if ($current_filename ne $delta->{filename}) {
+ if ($filenumber > 0) {
+ $delta->{previous_file_url} =
+ $url_builder->view_url($topicid, -1, $mode, $brmode,
+ $filenumber-1) . "#" .
$filenames[$filenumber-1];
+ }
+ if ($filenumber < $#filenames) {
+ $delta->{next_file_url} =
+ $url_builder->view_url($topicid, -1, $mode, $brmode,
+ $filenumber+1) . "#" .
$filenames[$filenumber+1];
+ }
+
+ # Keep track of the current filename being processed.
+ $filenumber++;
+ $current_filename = $delta->{filename};
}
- push @{ $comment_hash{$key} }, $comment;
}
- $vars->{'query'} = $query;
- $vars->{'comment_hash'} = \%comment_hash;
- $vars->{'comment_locations'} = [EMAIL PROTECTED];
- $vars->{'comment_location_map'} = \%comment_location_map;
+ # Annotate the deltas appropriately so that they can be easily rendered.
+ $delta_renderer->annotate_deltas();
+
+ $vars->{'deltas'} = [EMAIL PROTECTED];
# Fire the template for generating the view topic screen.
my $template = Codestriker::Http::Template->new("viewtopic");
@@ -277,17 +329,6 @@
# Retrieve the delta set comprising this review.
my $old_filename = "";
- # Determine which deltas are to be retrieved.
- my @deltas = ();
- if ($fview != -1) {
- # Get only the deltas for the selected file.
- @deltas = Codestriker::Model::Delta->get_delta_set($topicid, $fview);
- }
- else {
- # Get the whole delta data.
- @deltas = Codestriker::Model::Delta->get_delta_set($topicid, -1);
- }
-
# Now render the selected deltas.
for (my $i = 0; $i <= $#deltas; $i++) {
my $delta = $deltas[$i];
@@ -308,6 +349,7 @@
Codestriker::TopicListeners::Manager::topic_viewed($email, $topic);
}
+
# This function is used by all of the view topic tabs to fill out the
# common template items that are required by all, in addition to the view
# topic file action.
Index: UrlBuilder.pm
===================================================================
RCS file:
/cvsroot/codestriker/codestriker/lib/Codestriker/Http/UrlBuilder.pm,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- UrlBuilder.pm 11 Jun 2006 08:49:42 -0000 1.29
+++ UrlBuilder.pm 9 Mar 2008 19:57:08 -0000 1.30
@@ -219,6 +219,4 @@
return $self->{query}->url() . "?action=metrics_download";
}
-
-
1;
Index: DeltaRenderer.pm
===================================================================
RCS file: DeltaRenderer.pm
diff -N DeltaRenderer.pm
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ DeltaRenderer.pm 9 Mar 2008 19:57:08 -0000 1.1
@@ -0,0 +1,284 @@
+###############################################################################
+# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved.
+# [EMAIL PROTECTED]
+#
+# This program is free software; you can redistribute it and modify it under
+# the terms of the GPL.
+
+# Object for handling the computation of a delta for displaying to HTML.
+
+package Codestriker::Http::Delta;
+
+use strict;
+
+use HTML::Entities ();
+
+# Constructor.
+sub new {
+ my ($type, $topic, $comments, $deltas, $query, $mode, $brmode) = @_;
+
+ my $self = {};
+ $self->{topic} = $topic;
+ $self->{comments} = $comments;
+ $self->{deltas} = $deltas;
+ $self->{query} = $query;
+ $self->{mode} = $mode;
+ $self->{brmode} = $brmode;
+
+ # Build a hash from filenumber|fileline|new -> comment array, so that
+ # when rendering, lines can be coloured appropriately. Also build a list
+ # of what points in the review have a comment. Also record a mapping
+ # from filenumber|fileline|new -> the comment number.
+ my %comment_hash = ();
+ my @comment_locations = ();
+ my %comment_location_map = ();
+ for (my $i = 0; $i <= $#$comments; $i++) {
+ my $comment = $$comments[$i];
+ my $key = $comment->{filenumber} . "|" . $comment->{fileline} . "|" .
+ $comment->{filenew};
+ if (! exists $comment_hash{$key}) {
+ push @comment_locations, $key;
+ $comment_location_map{$key} = $#comment_locations;
+ }
+ push @{ $comment_hash{$key} }, $comment;
+ }
+ $self->{comment_hash} = \%comment_hash;
+ $self->{comment_locations} = [EMAIL PROTECTED];
+ $self->{comment_location_map} = \%comment_location_map;
+
+ bless $self, $type;
+}
+
+# Render $text with the appropriate anchor attributes set for
+# displaying any existing comments and a link for adding new ones.
+sub comment_link
+{
+ my ($self, $filenumber, $line, $new, $text) = @_;
+
+ # Determine the anchor and edit URL for this line number.
+ my $anchor = "$filenumber|$line|$new";
+ my $edit_url = "javascript:eo('$filenumber','$line','$new')";
+
+ # Set the anchor to this line number.
+ my $params = {};
+ $params->{name} = $anchor;
+
+ # Only set the href attribute if the comment is in open state.
+ if (!Codestriker::topic_readonly($self->{topic}->{topic_state})) {
+ $params->{href} = $edit_url;
+ }
+
+ # If a comment exists on this line, set span and the overlib hooks onto
+ # it.
+ my %comment_hash = %{ $self->{comment_hash} };
+ my %comment_location_map = %{ $self->{comment_location_map} };
+ my $comment_number = undef;
+ my $query = $self->{query};
+ if (exists $comment_hash{$anchor}) {
+ # Determine what comment number this anchor refers to.
+ $comment_number = $comment_location_map{$anchor};
+ $text = $query->span({-id=>"c$comment_number"}, "") .
+ $query->span({-class=>"com"}, $text);
+
+ # Determine what the next comment in line is.
+ my $index = -1;
+ my @comment_locations = @{ $self->{comment_locations} };
+ for ($index = 0; $index <= $#comment_locations; $index++) {
+ last if $anchor eq $comment_locations[$index];
+ }
+
+ $params->{onmouseover} =
+ "return overlib(comment_text[$index],STICKY,DRAGGABLE,ALTCUT);";
+ $params->{onmouseout} = "return nd();";
+ } else {
+ $text = $query->span({-class=>"nocom"}, $text);
+ }
+
+ return $query->a($params, $text);
+}
+
+# Go through all of the deltas, and append a line array for each delta with
+# enough information to render it easily.
+sub annotate_deltas
+{
+ my ($self) = @_;
+
+ foreach my $delta (@{ $self->{deltas} }) {
+
+ # Now process the text so that the display code has minimal work to do.
+ # Also apply appropriate transformations to the line as required.
+ # TODO: put this into a proper module/plugin framework to make it easier
+ # to extend/modify.
+ my @diff_lines = split /\n/, $delta->{text};
+ my $old_linenumber = $delta->{old_linenumber};
+ my $new_linenumber = $delta->{new_linenumber};
+ @{$self->{lines}} = ();
+ @{$self->{diff_old_lines}} = ();
+ @{$self->{diff_old_lines_numbers}} = ();
+ @{$self->{diff_new_lines}} = ();
+ @{$self->{diff_new_lines_numbers}} = ();
+ $self->{filenumber} = 0;
+ $self->{current_filename} = "";
+ for (my $i = 0; $i <= $#diff_lines; $i++) {
+ my $data = $diff_lines[$i];
+
+ # TODO: make these text transformations as plugins.
+ # TODO: perform syntax highlighting.
+ # TODO: perform LXR linking.
+ # TODO: tab adjust.
+ # TODO: line breaking.
+ # Escape the data.
+ $data = HTML::Entities::encode($data);
+
+ if ($data =~ /^\-(.*)$/o) {
+ # Line corresponding to old code.
+ push @{ $self->{diff_old_lines} }, $1;
+ push @{ $self->{diff_old_lines_numbers} }, $old_linenumber;
+ $old_linenumber++;
+ } elsif ($data =~ /^\+(.*)$/o) {
+ # Line corresponding to new code.
+ push @{ $self->{diff_new_lines} }, $1;
+ push @{ $self->{diff_new_lines_numbers} }, $new_linenumber;
+ $new_linenumber++;
+ } elsif ($data =~ /^\\/) {
+ # A diff comment such as "No newline at end of file" - ignore
it.
+ } else {
+ # Line corresponding to both sides. Strip the first space off
+ # the diff for proper alignment.
+ $data =~ s/^\s//;
+
+ # Render what has been currently recorded.
+ $self->_render_changes();
+
+ # Now that the diff changeset has been rendered, remove the
state data.
+ @{$self->{diff_old_lines}} = ();
+ @{$self->{diff_old_lines_numbers}} = ();
+ @{$self->{diff_new_lines}} = ();
+ @{$self->{diff_new_lines_numbers}} = ();
+
+ # Now render the line which is present on both sides.
+ my $line = {};
+ my $data_class =
+ $self->{mode} == $Codestriker::COLOURED_MODE ? "n" : "msn";
+ $line->{old_data} = $data;
+ $line->{old_data_line} =
+ $self->comment_link($self->{filenumber}, $old_linenumber,
+ 0, $old_linenumber);
+ $line->{old_data_class} = $data_class;
+ $line->{new_data} = $data;
+ $line->{new_data_line} =
+ $self->comment_link($self->{filenumber}, $new_linenumber,
+ 1, $new_linenumber);
+ $line->{new_data_class} = $data_class;
+ push @{$self->{lines}}, $line;
+ $old_linenumber++;
+ $new_linenumber++;
+ }
+ }
+
+ # Render any remaining diff segments.
+ $self->_render_changes();
+
+ # Store the processed lines with the delta object for rendering.
+ @{$delta->{lines}} = @{$self->{lines}};
+
+ if ($self->{current_filename} ne $delta->{filename}) {
+ # Keep track of the current filename being processed.
+ $self->{filenumber}++;
+ $self->{current_filename} = $delta->{filename};
+ }
+ }
+}
+
+# Annotate any accumlated diff changes.
+sub _render_changes
+{
+ my ($self) = @_;
+
+ # Determine the class to use for displaying the comments.
+ my ($old_col, $old_notpresent_col, $new_col, $new_notpresent_col);
+ if (@{$self->{diff_new_lines}} > 0 && @{$self->{diff_old_lines}} > 0) {
+ # Lines have been added and removed.
+ if ($self->{mode} == $Codestriker::COLOURED_MODE) {
+ $old_col = "c";
+ $old_notpresent_col = "cb";
+ $new_col = "c";
+ $new_notpresent_col = "cb";
+ } else {
+ $old_col = "msc";
+ $old_notpresent_col = "mscb";
+ $new_col = "msc";
+ $new_notpresent_col = "mscb";
+ }
+ } elsif (@{$self->{diff_new_lines}} > 0 && @{$self->{diff_old_lines}} ==
0) {
+ # New lines have been added.
+ if ($self->{mode} == $Codestriker::COLOURED_MODE) {
+ $old_col = "a";
+ $old_notpresent_col = "ab";
+ $new_col = "a";
+ $new_notpresent_col = "ab";
+ } else {
+ $old_col = "msa";
+ $old_notpresent_col = "msab";
+ $new_col = "msa";
+ $new_notpresent_col = "msab";
+ }
+ } else {
+ # Lines have been removed.
+ if ($self->{mode} == $Codestriker::COLOURED_MODE) {
+ $old_col = "r";
+ $old_notpresent_col = "rb";
+ $new_col = "r";
+ $new_notpresent_col = "rb";
+ } else {
+ $old_col = "msr";
+ $old_notpresent_col = "msrb";
+ $new_col = "msr";
+ $new_notpresent_col = "msrb";
+ }
+ }
+
+ my ($old_data, $new_data, $old_data_line, $new_data_line);
+ while (@{$self->{diff_old_lines}} > 0 || @{$self->{diff_new_lines}} > 0)
{
+
+ # Retrieve the next lines which were removed (if any).
+ if (@{$self->{diff_old_lines}} > 0) {
+ $old_data = shift @{$self->{diff_old_lines}};
+ $old_data_line = shift @{$self->{diff_old_lines_numbers}};
+ } else {
+ undef($old_data);
+ undef($old_data_line);
+ }
+
+ # Retrieve the next lines which were added (if any).
+ if (@{$self->{diff_new_lines}} > 0) {
+ $new_data = shift @{$self->{diff_new_lines}};
+ $new_data_line = shift @{$self->{diff_new_lines_numbers}};
+ } else {
+ undef($new_data);
+ undef($new_data_line);
+ }
+
+ # Set the colours to use appropriately depending on what is defined.
+ my $render_old_colour = $old_col;
+ my $render_new_colour = $new_col;
+ if (defined $old_data && ! defined $new_data) {
+ $render_new_colour = $new_notpresent_col;
+ } elsif (! defined $old_data && defined $new_data) {
+ $render_old_colour = $old_notpresent_col;
+ }
+
+ my $line = {};
+ $line->{old_data} = $old_data;
+ $line->{old_data_line} =
+ $self->comment_link($self->{filenumber}, $old_data_line, 0,
$old_data_line);
+ $line->{old_data_class} = $render_old_colour;
+ $line->{new_data} = $new_data;
+ $line->{new_data_line} =
+ $self->comment_link($self->{filenumber}, $new_data_line, 1,
$new_data_line);
+ $line->{new_data_class} = $render_new_colour;
+ push @{$self->{lines}}, $line;
+ }
+}
+
+1;
Index: viewtopic.html.tmpl
===================================================================
RCS file:
/cvsroot/codestriker/codestriker/template/en/default/viewtopic.html.tmpl,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- viewtopic.html.tmpl 28 Feb 2008 11:01:58 -0000 1.40
+++ viewtopic.html.tmpl 9 Mar 2008 19:57:08 -0000 1.41
@@ -70,15 +70,15 @@
[%# Display the filename with an internal link if its not binary. #%]
[% IF file.binary %]
- [% file.filename %]
+ [% file.filename | html_entity %]
[% ELSE %]
- <a href="[% file.href_filename_url %]">[% file.filename %]</a>
+ <a href="[% file.href_filename_url %]">[% file.filename |
html_entity %]</a>
[% END %]
</td>
[%# Display the revision information for modified files. #%]
[% IF rowstyle == "cf" %]
- <td class="[% rowstyle %]"> [% file.revision %]</td>
+ <td class="[% rowstyle %]"> [% file.revision | html_entity
%]</td>
[% END %]
[%# Display the numchange information for the file. #%]
@@ -90,6 +90,7 @@
</td>
</tr>
[% END %]
+ </table>
</table>
@@ -98,7 +99,9 @@
mode = mode %]
<p>
-[% FILTER $CommentLine filenumber = -1 line = -1 new = 1 %]Add General
Comment[% END %] to topic.
+<span class="general_comment">[% add_general_comment_element %]</span>
+
+[% PROCESS viewdeltas.html.tmpl deltas = deltas %]
[%# The perl script takes control from here, rendering the topic data. #%]
Index: viewdeltas.html.tmpl
===================================================================
RCS file: viewdeltas.html.tmpl
diff -N viewdeltas.html.tmpl
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ viewdeltas.html.tmpl 9 Mar 2008 19:57:08 -0000 1.1
@@ -0,0 +1,100 @@
+[%# HTML for rendering a set of deltas. #%]
+
+[% SET diff_current_filename = "" %]
+[% SET filenumber = 0 %]
+[% FOREACH delta = deltas %]
+[% FLUSH IF loop.count() % 10 == 1 %]
+ [%# Check if a heading for the current diff needs to be output. #%]
+ [% IF delta.filename != diff_current_filename %]
+
+ [%# Close off the previous table from the previous filename. #%]
+ [% IF loop.count() != 0 %]
+ </table>
+ [% END %]
+
+ <table width="100%" cellspacing="0" cellpadding="0" border="0">
+ <tr>
+ <td class="file" align="left">
+ [% IF delta.repository_file_view_url != "" %]
+ File
+ <a href="[% delta.repository_file_view_url %]">
+ [% delta.filename | html_entity %]
+ </a>
+ [% ELSE %]
+ File [% delta.filename | html_entity %]
+ [% END %]
+ </td>
+
+ <td class="file" align="right">
+ [% delta.add_file_comment_element %]
+ [% IF delta.previous_file_url != "" %]
+ <a href="[% delta.previous_file_url %]">[<<]</a>
+ [% END %]
+ <a href="#contents">[Top]</a>
+ [% IF delta.next_file_url != "" %]
+ <a href="[% delta.next_file_url %]">[>>]</a>
+ [% END %]
+ </td>
+ </tr>
+
+ [%# Output the diff description if it is present. #%]
+ [% IF delta.description != "" %]
+ <tr>
+ <td class="line" colspan="2">[% delta.description | html_entity
%]</td>
+ <td class="line" colspan="2">[% delta.description | html_entity
%]</td>
+ </tr>
+ [% END %]
+ </table>
+ [% filenumber = filenumber + 1 %]
+
+ [%# Make sure all the diffs are aligned in the same table. #%]
+ <table width="100%" cellspacing="0" cellpadding="0" border="0">
+ [% END %]
+
+ [%# Now output the delta header. #%]
+ [% SET diff_current_filename = delta.filename %]
+ <tr>
+ <td> </td><td> </td><td> </td><td> </td>
+ </tr>
+ <tr>
+ [% IF delta.view_old_full_url != "" %]
+ [%# Display heading with links to retrieve the entire file #%]
+ <td class="line" colspan="2">
+ <a href="javascript: myOpen('[% delta.view_old_full_url %]',
'Codestriker')">
+ Line [% delta.old_linenumber %]
+ </a>
+ |
+ <a href="javascript: myOpen('[% delta.view_old_full_both_url %]',
'Codestriker')">
+ Parallel
+ </a>
+ </td>
+ <td class="line" colspan="2">
+ <a href="javascript: myOpen('[% delta.view_new_full_url %]',
'Codestriker')">
+ Line [% delta.new_linenumber %]
+ </a>
+ |
+ <a href="javascript: myOpen('[% delta.view_new_full_both_url %]',
'Codestriker')">
+ Parallel
+ </a>
+ </td>
+ [% ELSE %]
+ [%# Just display the line numbers for the delta without any links. #%]
+ <td class="line" colspan="2">Line [% delta.old_linenumber %]</td>
+ <td class="line" colspan="2">Line [% delta.new_linenumber %]</td>
+ [% END %]
+ </tr>
+
+ [%# Now output the delta itself. #%]
+ [% FOREACH line = delta.lines %]
+ [% FLUSH IF loop.count() % 10 == 1 %]
+ <tr>
+ <td>[% line.old_data_line %]</td>
+ <td class="[% line.old_data_class %]">[% line.old_data %]</td>
+ <td>[% line.new_data_line %]</td>
+ <td class="[% line.new_data_class %]">[% line.new_data %]</td>
+ </tr>
+ [% END %]
+[% END %]
+
+[%# Close off the table from the last file's delta set. #%]
+ </table>
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Codestriker-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/codestriker-commits