Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/Config.pm |
— | — | @@ -0,0 +1,45 @@ |
| 2 | +# -*- Mode: perl; indent-tabs-mode: nil -*- |
| 3 | +# |
| 4 | +# The contents of this file are subject to the Mozilla Public |
| 5 | +# License Version 1.1 (the "License"); you may not use this file |
| 6 | +# except in compliance with the License. You may obtain a copy of |
| 7 | +# the License at http://www.mozilla.org/MPL/ |
| 8 | +# |
| 9 | +# Software distributed under the License is distributed on an "AS |
| 10 | +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 | +# implied. See the License for the specific language governing |
| 12 | +# rights and limitations under the License. |
| 13 | +# |
| 14 | +# The Original Code is the WeeklyReporting Bugzilla Extension. |
| 15 | +# |
| 16 | +# The Initial Developer of the Original Code is Chad Horohoe |
| 17 | +# Portions created by the Initial Developer are Copyright (C) 2010 the |
| 18 | +# Initial Developer. All Rights Reserved. |
| 19 | +# |
| 20 | +# Contributor(s): |
| 21 | +# Chad Horohoe <chad@anyonecanedit.org> |
| 22 | + |
| 23 | +package Bugzilla::Extension::WeeklyReporting; |
| 24 | +use strict; |
| 25 | + |
| 26 | +use constant NAME => 'WeeklyReporting'; |
| 27 | + |
| 28 | +use constant REQUIRED_MODULES => [ |
| 29 | + { |
| 30 | + package => 'DateTime', |
| 31 | + module => 'DateTime', |
| 32 | + }, |
| 33 | + { |
| 34 | + package => 'Getopt-Long', |
| 35 | + module => 'Getopt::Long', |
| 36 | + }, |
| 37 | + { |
| 38 | + package => 'Pod-Usage', |
| 39 | + module => 'Pod::Usage', |
| 40 | + } |
| 41 | +]; |
| 42 | + |
| 43 | +use constant OPTIONAL_MODULES => [ |
| 44 | +]; |
| 45 | + |
| 46 | +__PACKAGE__->NAME; |
Property changes on: trunk/tools/bugzilla/bugzilla-4.0/extensions/Config.pm |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 47 | + native |
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/sendReports.pl |
— | — | @@ -0,0 +1,74 @@ |
| 2 | +#!/usr/bin/perl -w |
| 3 | +# |
| 4 | +# The contents of this file are subject to the Mozilla Public |
| 5 | +# License Version 1.1 (the "License"); you may not use this file |
| 6 | +# except in compliance with the License. You may obtain a copy of |
| 7 | +# the License at http://www.mozilla.org/MPL/ |
| 8 | +# |
| 9 | +# Software distributed under the License is distributed on an "AS |
| 10 | +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 | +# implied. See the License for the specific language governing |
| 12 | +# rights and limitations under the License. |
| 13 | +# |
| 14 | +# The Original Code is the VCS Bugzilla Extension. |
| 15 | +# |
| 16 | +# The Initial Developer of the Original Code is Red Hat, Inc. |
| 17 | +# Portions created by the Initial Developer are Copyright (C) 2010 the |
| 18 | +# Initial Developer. All Rights Reserved. |
| 19 | +# |
| 20 | +# Contributor(s): |
| 21 | +# Max Kanat-Alexander <mkanat@everythingsolved.com> |
| 22 | + |
| 23 | +use strict; |
| 24 | +use diagnostics; |
| 25 | +use warnings; |
| 26 | +use lib qw(lib); |
| 27 | +use Getopt::Long; |
| 28 | +use Pod::Usage qq/pod2usage/; |
| 29 | +use DateTime; |
| 30 | +use Bugzilla; |
| 31 | + |
| 32 | +BEGIN { Bugzilla->extensions } |
| 33 | + |
| 34 | +my %switch; |
| 35 | +my $end_date = DateTime->now; |
| 36 | +my $begin_date = $end_date->clone(); |
| 37 | +$begin_date = $begin_date->subtract( days => 7 ); |
| 38 | + |
| 39 | +GetOptions(\%switch, 'help|h|?', 'noemail' ) || die $@; |
| 40 | + |
| 41 | +if ( $switch{'help'} ) { |
| 42 | + pod2usage({-exitval => 1}); |
| 43 | +} |
| 44 | + |
| 45 | +foreach my $report ( Bugzilla::Extension::WeeklyReporting->get_report_list( $begin_date, $end_date ) ) { |
| 46 | + if( $switch{'noemail'} ) { |
| 47 | + $report->printReport(); |
| 48 | + } else { |
| 49 | + $report->emailReport(); |
| 50 | + } |
| 51 | +} |
| 52 | + |
| 53 | +__END__ |
| 54 | + |
| 55 | +=head1 NAME |
| 56 | + |
| 57 | + sendReports.pl - Send reports scheduled for dispatch |
| 58 | + |
| 59 | +=head1 SYNOPSIS |
| 60 | + |
| 61 | + sendReports.pl --noemail |
| 62 | + |
| 63 | +=head1 OPTIONS |
| 64 | + |
| 65 | +=over |
| 66 | + |
| 67 | +=item B<--noemail> |
| 68 | + |
| 69 | +Just print the report, rather than sending the e-mail |
| 70 | + |
| 71 | +=back |
| 72 | + |
| 73 | +=head1 DESCRIPTION |
| 74 | + |
| 75 | +This script can be used to send reports on Bugzilla activity |
Property changes on: trunk/tools/bugzilla/bugzilla-4.0/extensions/sendReports.pl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 76 | + native |
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/lib/ReportBase.pm |
— | — | @@ -0,0 +1,49 @@ |
| 2 | +# -*- Mode: perl; indent-tabs-mode: nil -*- |
| 3 | +# |
| 4 | +# The contents of this file are subject to the Mozilla Public |
| 5 | +# License Version 1.1 (the "License"); you may not use this file |
| 6 | +# except in compliance with the License. You may obtain a copy of |
| 7 | +# the License at http://www.mozilla.org/MPL/ |
| 8 | +# |
| 9 | +# Software distributed under the License is distributed on an "AS |
| 10 | +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 | +# implied. See the License for the specific language governing |
| 12 | +# rights and limitations under the License. |
| 13 | +# |
| 14 | +# The Original Code is the WeeklyReporting Bugzilla Extension. |
| 15 | +# |
| 16 | +# The Initial Developer of the Original Code is Chad Horohoe |
| 17 | +# Portions created by the Initial Developer are Copyright (C) 2010 the |
| 18 | +# Initial Developer. All Rights Reserved. |
| 19 | +# |
| 20 | +# Contributor(s): |
| 21 | +# Chad Horohoe <chad@anyonecanedit.org> |
| 22 | + |
| 23 | +package Bugzilla::Extension::WeeklyReporting::ReportBase; |
| 24 | +use strict; |
| 25 | +use DateTime; |
| 26 | +use Bugzilla::Mailer; |
| 27 | +use Bugzilla::DB; |
| 28 | + |
| 29 | +sub new { |
| 30 | + my($class, $begin, $end) = @_; |
| 31 | + my $self = { |
| 32 | + start => $begin, |
| 33 | + stop => $end, |
| 34 | + dbh => Bugzilla->dbh |
| 35 | + }; |
| 36 | + bless($self, $class); |
| 37 | + return $self; |
| 38 | +} |
| 39 | + |
| 40 | +sub emailReport { |
| 41 | + MessageToMTA( get_report_text() ); |
| 42 | +} |
| 43 | + |
| 44 | +sub printReport { |
| 45 | + print get_report_text(); |
| 46 | +} |
| 47 | + |
| 48 | +sub get_report_text { return "Test\n"; } |
| 49 | + |
| 50 | +1; |
Property changes on: trunk/tools/bugzilla/bugzilla-4.0/extensions/lib/ReportBase.pm |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 51 | + native |
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/lib/Params.pm |
— | — | @@ -0,0 +1,59 @@ |
| 2 | +# -*- Mode: perl; indent-tabs-mode: nil -*- |
| 3 | +# |
| 4 | +# The contents of this file are subject to the Mozilla Public |
| 5 | +# License Version 1.1 (the "License"); you may not use this file |
| 6 | +# except in compliance with the License. You may obtain a copy of |
| 7 | +# the License at http://www.mozilla.org/MPL/ |
| 8 | +# |
| 9 | +# Software distributed under the License is distributed on an "AS |
| 10 | +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 | +# implied. See the License for the specific language governing |
| 12 | +# rights and limitations under the License. |
| 13 | +# |
| 14 | +# The Original Code is the WeeklyReporting Bugzilla Extension. |
| 15 | +# |
| 16 | +# The Initial Developer of the Original Code is Chad Horohoe |
| 17 | +# Portions created by the Initial Developer are Copyright (C) 2010 the |
| 18 | +# Initial Developer. All Rights Reserved. |
| 19 | +# |
| 20 | +# Contributor(s): |
| 21 | +# Chad Horohoe <chad@anyonecanedit.org> |
| 22 | + |
| 23 | +package Bugzilla::Extension::WeeklyReporting::Params; |
| 24 | +use strict; |
| 25 | + |
| 26 | +use Bugzilla::Constants; |
| 27 | +use Bugzilla::Error; |
| 28 | +use Bugzilla::Util; |
| 29 | + |
| 30 | +use constant get_param_list => ( |
| 31 | + { |
| 32 | + name => 'weeklyreporting_email', |
| 33 | + type => 't', |
| 34 | + default => '', |
| 35 | + checker => \&_check_email_list, |
| 36 | + } |
| 37 | +); |
| 38 | + |
| 39 | +# Validate the list of e-mail addresses |
| 40 | +sub _check_email_list { |
| 41 | + my ($value) = @_; |
| 42 | + foreach my $email (split ",", $value) { |
| 43 | + $email = trim($email); |
| 44 | + next if !$email; |
| 45 | + if ( !validate_email_syntax($email) ) { |
| 46 | + return "Invalid e-mail address"; |
| 47 | + } |
| 48 | + my $error_mode = Bugzilla->error_mode; |
| 49 | + Bugzilla->error_mode(ERROR_MODE_DIE); |
| 50 | + my $success = eval { |
| 51 | + trick_taint($email); |
| 52 | + 1; |
| 53 | + }; |
| 54 | + Bugzilla->error_mode($error_mode); |
| 55 | + return $@ if !$success; |
| 56 | + } |
| 57 | + return ""; |
| 58 | +} |
| 59 | + |
| 60 | +1; |
Property changes on: trunk/tools/bugzilla/bugzilla-4.0/extensions/lib/Params.pm |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 61 | + native |
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/Extension.pm |
— | — | @@ -0,0 +1,45 @@ |
| 2 | +# -*- Mode: perl; indent-tabs-mode: nil -*- |
| 3 | +# |
| 4 | +# The contents of this file are subject to the Mozilla Public |
| 5 | +# License Version 1.1 (the "License"); you may not use this file |
| 6 | +# except in compliance with the License. You may obtain a copy of |
| 7 | +# the License at http://www.mozilla.org/MPL/ |
| 8 | +# |
| 9 | +# Software distributed under the License is distributed on an "AS |
| 10 | +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 | +# implied. See the License for the specific language governing |
| 12 | +# rights and limitations under the License. |
| 13 | +# |
| 14 | +# The Original Code is the WeeklyReporting Bugzilla Extension. |
| 15 | +# |
| 16 | +# The Initial Developer of the Original Code is Chad Horohoe |
| 17 | +# Portions created by the Initial Developer are Copyright (C) 2010 the |
| 18 | +# Initial Developer. All Rights Reserved. |
| 19 | +# |
| 20 | +# Contributor(s): |
| 21 | +# Chad Horohoe <chad@anyonecanedit.org> |
| 22 | + |
| 23 | +package Bugzilla::Extension::WeeklyReporting; |
| 24 | +use strict; |
| 25 | +use base qw(Bugzilla::Extension); |
| 26 | + |
| 27 | +our $VERSION = '0.1'; |
| 28 | + |
| 29 | +sub config_add_panels { |
| 30 | + my ($self, $args) = @_; |
| 31 | + my $modules = $args->{'panel_modules'}; |
| 32 | + $modules->{'WeeklyReporting'} = 'Bugzilla::Extension::WeeklyReporting::Params'; |
| 33 | +} |
| 34 | + |
| 35 | +# List of reports used below |
| 36 | +use Bugzilla::Extension::WeeklyReporting::WeekAtAGlance; |
| 37 | + |
| 38 | +# When adding a report module above, be sure to push it into the array below |
| 39 | +sub get_report_list { |
| 40 | + my( $self, $begin, $end ) = @_; |
| 41 | + my @reportList; |
| 42 | +# push @reportList, new Bugzilla::Extension::WeeklyReporting::WeekAtAGlance( $begin, $end ); |
| 43 | + return @reportList; |
| 44 | +} |
| 45 | + |
| 46 | +__PACKAGE__->NAME; |
Property changes on: trunk/tools/bugzilla/bugzilla-4.0/extensions/Extension.pm |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 47 | + native |
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/README.txt |
— | — | @@ -0,0 +1,44 @@ |
| 2 | + |
| 3 | + WeeklyReporting, version 0.1 |
| 4 | + |
| 5 | + This Bugzilla extension provides a functionality to send weekly |
| 6 | + reports to user(s) regarding the week's bug activity |
| 7 | + |
| 8 | + |
| 9 | + WHAT YOU GET |
| 10 | + |
| 11 | + After you set up everything as described below, you'll send weekly |
| 12 | + status reports to the e-mail addresses specified. |
| 13 | + |
| 14 | + |
| 15 | + OVERVIEW |
| 16 | + |
| 17 | + This extension was created to replace the ad-hoc script used by |
| 18 | + Wikimedia to generate weekly Bugzilla reports. Right now, the |
| 19 | + original report is the only one. However, there could be more, |
| 20 | + in theory. |
| 21 | + |
| 22 | + |
| 23 | + INSTALLATION |
| 24 | + |
| 25 | + Configuration of WeeklyReporting |
| 26 | + |
| 27 | + - just store the module in the extension folder of your 3.6 |
| 28 | + Bugzilla installation. It will be activated automatically |
| 29 | + and requires no further configuraiton. |
| 30 | + |
| 31 | + Configuration of Bugzilla |
| 32 | + |
| 33 | + - Use the Parameters interface or edit data/params directly to |
| 34 | + set up the following values |
| 35 | + |
| 36 | + # weeklyreporting_email - E-mail address (or more than one, |
| 37 | + by comma-delimiting them |
| 38 | + |
| 39 | + NOTES: |
| 40 | + - Cannot currently configure reports to have different recipients |
| 41 | + |
| 42 | + |
| 43 | +Keywords: reporting, statistics |
| 44 | + |
| 45 | + |
Property changes on: trunk/tools/bugzilla/bugzilla-4.0/extensions/README.txt |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 46 | + native |
Index: trunk/tools/bugzilla/bugzilla-4.0/extensions/template/en/default/admin/params/weeklyreporting.html.tmpl |
— | — | @@ -0,0 +1,33 @@ |
| 2 | +[%# The contents of this file are subject to the Mozilla Public |
| 3 | + # License Version 1.1 (the "License"); you may not use this file |
| 4 | + # except in compliance with the License. You may obtain a copy of |
| 5 | + # the License at http://www.mozilla.org/MPL/ |
| 6 | + # |
| 7 | + # Software distributed under the License is distributed on an "AS |
| 8 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + # implied. See the License for the specific language governing |
| 10 | + # rights and limitations under the License. |
| 11 | + # |
| 12 | + # The Original Code is the WeeklyReporting Bugzilla Extension. |
| 13 | + # |
| 14 | + # The Initial Developer of the Original Code is Chad Horohoe |
| 15 | + # Portions created by the Initial Developer are Copyright (C) 2010 the |
| 16 | + # Initial Developer. All Rights Reserved. |
| 17 | + # |
| 18 | + # Contributor(s): |
| 19 | + # Chad Horohoe <chad@anyonecanedit.org>#%] |
| 20 | + #%] |
| 21 | +[% |
| 22 | + title = "Weekly Reporting" |
| 23 | + desc = "Manage weekly reporting configuration" |
| 24 | +%] |
| 25 | + |
| 26 | +[% weeklyreporting_weekataglanceemail = BLOCK %] |
| 27 | + |
| 28 | + <p>List of comma-delimited e-mail addresses to send the Week-At-A-Glance reports to</p> |
| 29 | + |
| 30 | +[% END %] |
| 31 | + |
| 32 | +[% param_descs = { |
| 33 | + "weeklyreporting_weekataglanceemail" => weeklyreporting_weekataglanceemail, |
| 34 | +} %] |
Property changes on: trunk/tools/bugzilla/bugzilla-4.0/extensions/template/en/default/admin/params/weeklyreporting.html.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 35 | + native |
Added: svn:executable |
2 | 36 | + * |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/scripts/bugzilla_report.php |
— | — | @@ -0,0 +1,267 @@ |
| 2 | +<?php error_reporting(E_ALL); |
| 3 | + |
| 4 | +function getBugsPerProduct( $begin_date, $end_date ) { |
| 5 | + print "New Bugs Per Product\n\n"; |
| 6 | + return <<<END |
| 7 | +SELECT |
| 8 | + name, count(*) |
| 9 | +FROM |
| 10 | + bugs |
| 11 | +JOIN |
| 12 | + products |
| 13 | + on |
| 14 | + product_id = products.id |
| 15 | +WHERE |
| 16 | + bug_status = 'NEW' |
| 17 | + and creation_ts |
| 18 | +BETWEEN |
| 19 | + "$begin_date" |
| 20 | + and |
| 21 | + "$end_date" |
| 22 | +GROUP BY |
| 23 | + product_id |
| 24 | +LIMIT 5; |
| 25 | +END; |
| 26 | +} |
| 27 | + |
| 28 | +function getBugsPerComponent( $begin_date, $end_date ) { |
| 29 | + print "New Bugs Per Component\n\n"; |
| 30 | + return <<<END |
| 31 | +SELECT |
| 32 | + name, count(*) as total |
| 33 | +FROM |
| 34 | + bugs |
| 35 | +JOIN |
| 36 | + components |
| 37 | + on |
| 38 | + component_id = components.id |
| 39 | +WHERE |
| 40 | + bug_status = 'NEW' |
| 41 | + and |
| 42 | + creation_ts |
| 43 | +BETWEEN |
| 44 | + "$begin_date" |
| 45 | + and |
| 46 | + "$end_date" |
| 47 | +GROUP BY |
| 48 | + component_id |
| 49 | +ORDER BY |
| 50 | + total |
| 51 | +DESC |
| 52 | +LIMIT |
| 53 | + 5; |
| 54 | + |
| 55 | +END; |
| 56 | +} |
| 57 | + |
| 58 | +function getBugsResolvedPerUser( $begin_date, $end_date ) { |
| 59 | + print "Top 5 Bug Resolvers\n\n"; |
| 60 | + return <<<END |
| 61 | +SELECT |
| 62 | + login_name, count(*) as total |
| 63 | +FROM |
| 64 | + bugs_activity |
| 65 | +JOIN |
| 66 | + profiles |
| 67 | + on |
| 68 | + who = profiles.userid |
| 69 | +WHERE |
| 70 | + added = 'RESOLVED' |
| 71 | + and |
| 72 | + bug_when |
| 73 | +BETWEEN |
| 74 | + "$begin_date" |
| 75 | + and |
| 76 | + "$end_date" |
| 77 | +GROUP BY |
| 78 | + who |
| 79 | +ORDER BY |
| 80 | + total |
| 81 | +DESC |
| 82 | +LIMIT |
| 83 | + 5; |
| 84 | +END; |
| 85 | +} |
| 86 | + |
| 87 | +function getBugResolutions( $begin_date, $end_date, $resolution ) { |
| 88 | + $resolution = mysql_real_escape_string( $resolution ); |
| 89 | + $resolution = "'$resolution'"; |
| 90 | + |
| 91 | + return <<<END |
| 92 | +SELECT |
| 93 | + count(*) |
| 94 | +FROM |
| 95 | + bugs |
| 96 | +WHERE |
| 97 | + resolution = $resolution |
| 98 | + and delta_ts |
| 99 | +BETWEEN |
| 100 | + "$begin_date" |
| 101 | + and |
| 102 | + "$end_date" |
| 103 | +END; |
| 104 | +} |
| 105 | + |
| 106 | +function getBugsChangingStatus( $begin_date, $end_date, $state ) { |
| 107 | + $state = mysql_real_escape_string( $state ); |
| 108 | + $state = "'$state'"; |
| 109 | + |
| 110 | + return <<<END |
| 111 | +SELECT |
| 112 | + count(*) |
| 113 | +FROM |
| 114 | + bugs |
| 115 | +WHERE |
| 116 | + bug_status = $state |
| 117 | + and delta_ts |
| 118 | +BETWEEN |
| 119 | + "$begin_date" |
| 120 | + and |
| 121 | + "$end_date" |
| 122 | +END; |
| 123 | +} |
| 124 | + |
| 125 | +function getTotalOpenBugs() { |
| 126 | + return <<<END |
| 127 | +SELECT |
| 128 | + count(*) |
| 129 | +FROM |
| 130 | + bugs |
| 131 | +WHERE |
| 132 | + bug_status = 'ASSIGNED' or |
| 133 | + bug_status = 'NEW' or |
| 134 | + bug_status = 'REOPENED'; |
| 135 | +END; |
| 136 | +} |
| 137 | + |
| 138 | + |
| 139 | +function formatOutput( $result ) { |
| 140 | + while ( $row = mysql_fetch_row( $result ) ) { |
| 141 | + if ( is_array( $row ) ) { |
| 142 | + foreach( $row as $row_i ) { |
| 143 | + $row_i = str_replace( '@', ' [AT] ', $row_i ); //strip out any easy scrapes |
| 144 | + print pack( 'A36', ( $row_i ) ); |
| 145 | + } |
| 146 | + } |
| 147 | + else { |
| 148 | + print "0\n"; |
| 149 | + } |
| 150 | + print "\n"; |
| 151 | + } |
| 152 | +} |
| 153 | + |
| 154 | +function reportFailure( $text ) { |
| 155 | + print "Wikimedia Bugzilla report (FAILED), $text "; |
| 156 | + die( "FAILED\n\n$text\n" ); |
| 157 | +} |
| 158 | + |
| 159 | +# main |
| 160 | + |
| 161 | +$options = getopt( 'b:e:h' ); |
| 162 | + |
| 163 | +if ( isset( $options['h'] ) ) { |
| 164 | + $line = "bugzilla_report.php: usage bugzilla_report.php [-b|-e] \n"; |
| 165 | + $line .= " -b start date\n"; |
| 166 | + $line .= " -e end date\n"; |
| 167 | + |
| 168 | + die( $line ); |
| 169 | +} |
| 170 | + |
| 171 | +if ( !isset( $options['e'] ) ) { |
| 172 | + $end_date = strtotime( 'now' ); |
| 173 | +} else { |
| 174 | + $end_date = strtotime( $options['e'] ); |
| 175 | +} |
| 176 | + |
| 177 | +if ( !isset( $options['b'] ) ) { |
| 178 | + $begin_date = $end_date - 86400*7 ; |
| 179 | +} else { |
| 180 | + $begin_date = strtotime( $options['b'] ); |
| 181 | +} |
| 182 | + |
| 183 | +print "MediaWiki Bugzilla Report for " . date('F d, Y', $begin_date) . " - " . date('F d, Y', $end_date) . "\n\n"; |
| 184 | + |
| 185 | +#Needs user/pass info |
| 186 | +$ok = mysql_connect('', '', ''); |
| 187 | +if ( !$ok ) { |
| 188 | + reportFailure( 'DB connection failure' ); |
| 189 | +} |
| 190 | + |
| 191 | +$ok = mysql_select_db( 'bugzilla3' ); |
| 192 | +if ( !$ok ) { |
| 193 | + reportFailure( 'DB selection failure' ); |
| 194 | +} |
| 195 | + |
| 196 | +$reportsPerItem = array( |
| 197 | + 'getBugsPerComponent', |
| 198 | + 'getBugsPerProduct', |
| 199 | + 'getBugsResolvedPerUser', |
| 200 | +); |
| 201 | + |
| 202 | +$statesToRun = array( |
| 203 | + 'NEW', |
| 204 | + 'ASSIGNED', |
| 205 | + 'REOPENED', |
| 206 | + 'RESOLVED', |
| 207 | +); |
| 208 | + |
| 209 | +$resolutionsToRun = array( |
| 210 | + 'FIXED', |
| 211 | + 'REMIND', |
| 212 | + 'INVALID', |
| 213 | + 'DUPLICATE', |
| 214 | + 'WONTFIX', |
| 215 | + 'WORKSFORME', |
| 216 | + 'LATER', |
| 217 | + 'MOVED', |
| 218 | +); |
| 219 | + |
| 220 | +$totalStatistics = array( |
| 221 | + 'getTotalOpenBugs', |
| 222 | +); |
| 223 | + |
| 224 | + |
| 225 | +print "Status changes this week\n\n"; |
| 226 | + |
| 227 | +foreach( $statesToRun as $state ) { |
| 228 | + $sql = getBugsChangingStatus( date( 'Y-m-d', $begin_date ), date( 'Y-m-d', $end_date ), $state); |
| 229 | + $result = mysql_query( $sql ); |
| 230 | + if ( !$result ) { |
| 231 | + reportFailure( 'Query failure' ); |
| 232 | + } |
| 233 | + print pack( 'A23A3', "Bugs $state", ':' ); |
| 234 | + formatOutput( $result ); |
| 235 | +} |
| 236 | + |
| 237 | +foreach( $totalStatistics as $report ) { |
| 238 | + $sql = getTotalOpenBugs(); |
| 239 | + $result = mysql_query( $sql ); |
| 240 | + if ( !$result ) |
| 241 | + reportFailure( 'Query failure' ); |
| 242 | + print "\nTotal bugs still open: "; |
| 243 | + formatOutput( $result ); |
| 244 | +} |
| 245 | + |
| 246 | +print "\nResolutions for the week:\n\n"; |
| 247 | + |
| 248 | +foreach( $resolutionsToRun as $resolution ) { |
| 249 | + $sql = getBugResolutions( date( 'Y-m-d', $begin_date ), date( 'Y-m-d', $end_date ), $resolution ); |
| 250 | + $result = mysql_query( $sql ); |
| 251 | + if ( !$result ) { |
| 252 | + reportFailure( 'Query failure' ); |
| 253 | + } |
| 254 | + print pack( 'A23A3', "Bugs marked $resolution", ':' ); |
| 255 | + formatOutput( $result ); |
| 256 | +} |
| 257 | + |
| 258 | +print "\nSpecific Product/Component Resolutions & User Metrics \n\n"; |
| 259 | + |
| 260 | +foreach( $reportsPerItem as $report) { |
| 261 | + $sql = $report( date( 'Y-m-d', $begin_date), date( 'Y-m-d', $end_date ) ); |
| 262 | + $result = mysql_query( $sql ); |
| 263 | + if ( !$result ) { |
| 264 | + reportFailure( 'Query failure' ); |
| 265 | + } |
| 266 | + formatOutput( $result ); |
| 267 | + print "\n"; |
| 268 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/scripts/bugzilla_report.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 269 | + native |
Added: svn:executable |
2 | 270 | + * |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/admin.css |
— | — | @@ -0,0 +1,115 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Marc Schumann <wurblzap@gmail.com> |
| 15 | + */ |
| 16 | + |
| 17 | +.warningmessages, .criticalmessages { |
| 18 | + background-color: white; |
| 19 | + border-style: solid; |
| 20 | + border-width: 1px; |
| 21 | + padding: 1ex 1ex 1ex 4ex; |
| 22 | + margin: 1ex; |
| 23 | +} |
| 24 | + |
| 25 | +.warningmessages { |
| 26 | + border-color: yellow; |
| 27 | +} |
| 28 | + |
| 29 | +.criticalmessages { |
| 30 | + border-color: red; |
| 31 | +} |
| 32 | + |
| 33 | +.alert { |
| 34 | + color: red; |
| 35 | + background-color: inherit; |
| 36 | +} |
| 37 | + |
| 38 | +p.areyoureallyreallysure { |
| 39 | + color: red; |
| 40 | + font-size: 120%; |
| 41 | + font-weight: bold; |
| 42 | +} |
| 43 | + |
| 44 | +tr.param_disabled { |
| 45 | + background-color: lightgrey; |
| 46 | +} |
| 47 | + |
| 48 | +td.admin_links { |
| 49 | + width: 50%; |
| 50 | + padding: 1em; |
| 51 | + vertical-align: top; |
| 52 | +} |
| 53 | + |
| 54 | +td.admin_links dt { |
| 55 | + margin-top: 1em; |
| 56 | +} |
| 57 | + |
| 58 | +td.admin_links dt.forbidden, td.admin_links dd.forbidden { |
| 59 | + font-size: smaller; |
| 60 | + font-style: italic; |
| 61 | + color: #aaa; |
| 62 | +} |
| 63 | + |
| 64 | +td.admin_links dt.forbidden a, td.admin_links dd.forbidden a { |
| 65 | + text-decoration: none; |
| 66 | + color: inherit; |
| 67 | + cursor: default; |
| 68 | +} |
| 69 | + |
| 70 | +.col-header { |
| 71 | + width: 8em; |
| 72 | +} |
| 73 | + |
| 74 | +.checkbox-cell { |
| 75 | + border: 1px black solid; |
| 76 | +} |
| 77 | + |
| 78 | +/* Grey-green color */ |
| 79 | +.open-status { |
| 80 | + color: #286; |
| 81 | +} |
| 82 | + |
| 83 | +/* Brown-red color */ |
| 84 | +.closed-status { |
| 85 | + color: #a63; |
| 86 | +} |
| 87 | + |
| 88 | +/* Dark green color */ |
| 89 | +.checked { |
| 90 | + background-color: #5b4; |
| 91 | +} |
| 92 | + |
| 93 | +/* Dark red color */ |
| 94 | +td.forbidden { |
| 95 | + background-color: #811; |
| 96 | +} |
| 97 | + |
| 98 | +/* Light green color */ |
| 99 | +td.set { |
| 100 | + background-color: #efe; |
| 101 | +} |
| 102 | + |
| 103 | +/* Light red color */ |
| 104 | +td.unset { |
| 105 | + background-color: #fee; |
| 106 | +} |
| 107 | + |
| 108 | +tr.highlight:hover { |
| 109 | + background-color: yellow; |
| 110 | +} |
| 111 | + |
| 112 | +th.title { |
| 113 | + font-size: larger; |
| 114 | + text-align: center; |
| 115 | + vertical-align: middle; |
| 116 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/admin.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 117 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/help.css |
— | — | @@ -0,0 +1,41 @@ |
| 2 | +/* ***** BEGIN LICENSE BLOCK ***** |
| 3 | + * Version: MPL 1.1 |
| 4 | + * |
| 5 | + * The contents of this file are subject to the Mozilla Public License Version |
| 6 | + * 1.1 (the "License"); you may not use this file except in compliance with |
| 7 | + * the License. You may obtain a copy of the License at |
| 8 | + * http://www.mozilla.org/MPL/ |
| 9 | + * |
| 10 | + * Software distributed under the License is distributed on an "AS IS" basis, |
| 11 | + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| 12 | + * for the specific language governing rights and limitations under the |
| 13 | + * License. |
| 14 | + * |
| 15 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 16 | + * |
| 17 | + * The Initial Developer of the Original Code is |
| 18 | + * Netscape Communications Corporation. |
| 19 | + * Portions created by the Initial Developer are Copyright (C) 1998 |
| 20 | + * the Initial Developer. All Rights Reserved. |
| 21 | + * |
| 22 | + * Contributor(s): |
| 23 | + * Gervase Markham <gerv@gerv.net> |
| 24 | + * |
| 25 | + * ***** END LICENSE BLOCK ***** */ |
| 26 | + |
| 27 | +/* Help system */ |
| 28 | +#helpDiv { |
| 29 | + border-style: solid; |
| 30 | + border-color: #F0A000; |
| 31 | + background-color: white; |
| 32 | + padding: 5px; |
| 33 | + position: absolute; |
| 34 | + z-index: 2; |
| 35 | +} |
| 36 | + |
| 37 | +#helpIframe { |
| 38 | + overflow: hidden; |
| 39 | + position: absolute; |
| 40 | + z-index: 1; |
| 41 | + display: none; |
| 42 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/help.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 43 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/bug_activity.css |
— | — | @@ -0,0 +1,28 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * The Initial Developer of the Original Code is Mike Schrag. |
| 15 | + * Portions created by Marc Schumann are Copyright (c) 2007 Mike Schrag. |
| 16 | + * All rights reserved. |
| 17 | + * |
| 18 | + * Contributor(s): Mike Schrag <mschrag@pobox.com> |
| 19 | + * Byron Jones <bugzilla@glob.com.au> |
| 20 | + * Marc Schumann <wurblzap@gmail.com> |
| 21 | + */ |
| 22 | + |
| 23 | +table.bz_bugactivity td { |
| 24 | + padding: 0.5em 0.25em; |
| 25 | + width: auto; |
| 26 | +} |
| 27 | +tr.bz_bugactivityitem:hover { |
| 28 | + background-color: #f0f0f0; |
| 29 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/bug_activity.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 30 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/show_multiple.css |
— | — | @@ -0,0 +1,52 @@ |
| 2 | +hr {margin: 20px auto 40px} |
| 3 | + |
| 4 | +.bz_private { color:darkred } |
| 5 | + |
| 6 | +h1 { |
| 7 | + font-size: 2em; |
| 8 | + margin-bottom: 10px; |
| 9 | +} |
| 10 | + |
| 11 | +/* bugfields is table of all fields and values */ |
| 12 | +.bugfields { |
| 13 | + font-size: small; |
| 14 | + background: #eee; |
| 15 | + padding: 5px; |
| 16 | + border: 1px solid silver; |
| 17 | + width: 100%; |
| 18 | +} |
| 19 | + |
| 20 | +.bugfields tr { |
| 21 | + vertical-align: top; |
| 22 | +} |
| 23 | + |
| 24 | +.bugfields th { |
| 25 | + width: 10em; |
| 26 | + text-align: left; |
| 27 | + font-weight: normal; |
| 28 | + line-height: 150%; |
| 29 | +} |
| 30 | + |
| 31 | +.bugfields td { |
| 32 | + font-weight: bold; |
| 33 | + line-height: 150%; |
| 34 | +} |
| 35 | + |
| 36 | +.bugfields .rightcell { |
| 37 | + padding-left: 10px; |
| 38 | +} |
| 39 | + |
| 40 | +/* set line-height to normal for nested tables of bugfields table */ |
| 41 | +.bugfields table th, .bugfields table td { |
| 42 | + line-height: 100%; |
| 43 | + width: auto; |
| 44 | +} |
| 45 | + |
| 46 | +.bugfields table.timetracking th, .bugfields table.timetracking td { |
| 47 | + width: 10em; |
| 48 | +} |
| 49 | + |
| 50 | +.error { |
| 51 | + color: red; |
| 52 | + font-weight: bold; |
| 53 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/show_multiple.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 54 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/duplicates.css |
— | — | @@ -0,0 +1,34 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * The Initial Developer of the Original Code is Netscape Communications |
| 15 | + * Corporation. Portions created by Netscape are |
| 16 | + * Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + * Rights Reserved. |
| 18 | + * |
| 19 | + * Contributor(s): Myk Melez <myk@mozilla.org> |
| 20 | + */ |
| 21 | + |
| 22 | +tree#results-tree { |
| 23 | + margin-right: 0px; |
| 24 | + border-right-width: 0px; |
| 25 | + margin-left: 0px; |
| 26 | + border-left-width: 0px; |
| 27 | +} |
| 28 | + |
| 29 | +treechildren:-moz-tree-cell-text(resolution-FIXED) { |
| 30 | + text-decoration: line-through; |
| 31 | +} |
| 32 | + |
| 33 | +treecol#id_column { width: 6em; } |
| 34 | +treecol#duplicate_count_column { width: 5em; } |
| 35 | +treecol#duplicate_delta_column { width: 5em; } |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/duplicates.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 36 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/panel.css |
— | — | @@ -0,0 +1,37 @@ |
| 2 | +body |
| 3 | + { |
| 4 | + font-family: sans-serif; |
| 5 | + font-size: 10pt; |
| 6 | + background-color: white; |
| 7 | + } |
| 8 | + |
| 9 | +ul |
| 10 | + { |
| 11 | + padding-left: 12px; |
| 12 | + } |
| 13 | + |
| 14 | +radio |
| 15 | + { |
| 16 | + -moz-user-select: ignore; |
| 17 | + } |
| 18 | + |
| 19 | +.text-link |
| 20 | + { |
| 21 | + margin-left: 3px; |
| 22 | + } |
| 23 | + |
| 24 | +.text-link:hover |
| 25 | + { |
| 26 | + text-decoration: underline; |
| 27 | + cursor: pointer; |
| 28 | + } |
| 29 | + |
| 30 | +.descriptive-content |
| 31 | + { |
| 32 | + color: #AAAAAA; |
| 33 | + } |
| 34 | + |
| 35 | +.descriptive-content[focused=true] |
| 36 | + { |
| 37 | + color: black; |
| 38 | + } |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/panel.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 39 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global.css |
— | — | @@ -0,0 +1,423 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * The Initial Developer of the Original Code is Netscape Communications |
| 15 | + * Corporation. Portions created by Netscape are |
| 16 | + * Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + * Rights Reserved. |
| 18 | + * |
| 19 | + * Contributor(s): Byron Jones <bugzilla@glob.com.au> |
| 20 | + * Christian Reis <kiko@async.com.br> |
| 21 | + * Vitaly Harisov <vitaly@rathedg.com> |
| 22 | + * Svetlana Harisova <light@rathedg.com> |
| 23 | + * Marc Schumann <wurblzap@gmail.com> |
| 24 | + * Pascal Held <paheld@gmail.com> |
| 25 | + */ |
| 26 | + |
| 27 | +/* global (begin) */ |
| 28 | +/* global (end) */ |
| 29 | + |
| 30 | +/* header (begin) */ |
| 31 | + |
| 32 | + #message { |
| 33 | + border: 1px solid red; |
| 34 | + margin: 0.3em 0em; |
| 35 | + padding: 0.3em; |
| 36 | + color: green; |
| 37 | + } |
| 38 | + |
| 39 | + form.mini_login input.bz_login { |
| 40 | + width: 10em; |
| 41 | + } |
| 42 | + form.mini_login input.bz_password { |
| 43 | + width: 6em; |
| 44 | + } |
| 45 | + form.mini_login input.bz_remember { |
| 46 | + margin: 0; |
| 47 | + } |
| 48 | + .bz_mini_login_help { |
| 49 | + color: #777; |
| 50 | + } |
| 51 | + |
| 52 | +/* header (end) */ |
| 53 | + |
| 54 | + |
| 55 | +/* banner (end) */ |
| 56 | + |
| 57 | +/* titles (begin) */ |
| 58 | + #titles { |
| 59 | + width: 100%; |
| 60 | + background-color: #404D6C; |
| 61 | + color: #fff; |
| 62 | + -moz-border-radius-topleft: 5px; |
| 63 | + -moz-border-radius-topright: 5px; |
| 64 | + font-size: 110%; |
| 65 | + margin: 0; |
| 66 | + padding: 0.5em; |
| 67 | + vertical-align: bottom; |
| 68 | + } |
| 69 | + |
| 70 | + #titles a { |
| 71 | + color: #fff; |
| 72 | + } |
| 73 | + |
| 74 | + #titles p { |
| 75 | + margin: 0; |
| 76 | + padding: 0; |
| 77 | + } |
| 78 | + |
| 79 | + #titles #title { |
| 80 | + font-weight: bold; |
| 81 | + white-space: nowrap; |
| 82 | + } |
| 83 | + |
| 84 | + #titles #subtitle { |
| 85 | + font-weight: normal; |
| 86 | + width: 100%; |
| 87 | + text-align: center; |
| 88 | + } |
| 89 | + |
| 90 | + #titles #information { |
| 91 | + font-weight: normal; |
| 92 | + text-align: right; |
| 93 | + font-size: 90%; |
| 94 | + white-space: nowrap; |
| 95 | + } |
| 96 | + |
| 97 | +/* titles (end) */ |
| 98 | + |
| 99 | +/* footer (begin) |
| 100 | + * See also the "header" section for styles that apply |
| 101 | + * to both the header and footer. |
| 102 | + */ |
| 103 | +/* footer (end) */ |
| 104 | + |
| 105 | + |
| 106 | +/* generic (begin) */ |
| 107 | + a { |
| 108 | + color: #039; |
| 109 | + } |
| 110 | + |
| 111 | + a:visited { |
| 112 | + color: #636; |
| 113 | + } |
| 114 | + |
| 115 | + a:hover { |
| 116 | + color: #333; |
| 117 | + } |
| 118 | + |
| 119 | + a:active { |
| 120 | + color: #000; |
| 121 | + } |
| 122 | + |
| 123 | + .clickable_area { |
| 124 | + cursor: pointer; |
| 125 | + } |
| 126 | +/* generic (end) */ |
| 127 | + |
| 128 | +/* Links that control whether or not something is visible. */ |
| 129 | +a.controller { |
| 130 | + font-size: 115%; |
| 131 | +} |
| 132 | + |
| 133 | +div#docslinks { |
| 134 | + float: right; |
| 135 | + border: 1px solid black; |
| 136 | + padding: 1ex; |
| 137 | + font-size: 80%; |
| 138 | +} |
| 139 | + |
| 140 | +#docslinks h2 { |
| 141 | + margin: 0; |
| 142 | +} |
| 143 | + |
| 144 | +.bz_obsolete { |
| 145 | + text-decoration: line-through; |
| 146 | +} |
| 147 | +.bz_inactive { |
| 148 | + text-decoration: line-through; |
| 149 | +} |
| 150 | +.bz_closed, |
| 151 | +.bz_CLOSED td { |
| 152 | + text-decoration: line-through; |
| 153 | +} |
| 154 | +.bz_private { |
| 155 | + color: darkred; |
| 156 | + background: #f3eeee; |
| 157 | +} |
| 158 | +.bz_disabled { |
| 159 | + color: #a0a0a0; |
| 160 | +} |
| 161 | + |
| 162 | +/************/ |
| 163 | +/* Comments */ |
| 164 | +/************/ |
| 165 | + |
| 166 | +.bz_comment { |
| 167 | + margin-bottom: 2em; |
| 168 | +} |
| 169 | + |
| 170 | +/* The rules for these classes make international text wrap correctly, |
| 171 | + even for languages like Japanese that have no spaces. */ |
| 172 | +.bz_comment_text, .uneditable_textarea { |
| 173 | + font-family: monospace; |
| 174 | + /* Note that these must all be on separate lines or they stop |
| 175 | + working in Konqueror. */ |
| 176 | + white-space: pre-wrap; /* CSS 3 & 2.1 */ |
| 177 | + white-space: -moz-pre-wrap; /* Gecko */ |
| 178 | + white-space: -pre-wrap; /* Opera 4-6 */ |
| 179 | + white-space: -o-pre-wrap; /* Opera 7 */ |
| 180 | +} |
| 181 | + |
| 182 | +.bz_comment_text { |
| 183 | + width: 50em; |
| 184 | +} |
| 185 | + |
| 186 | +.bz_comment_user, .bz_comment_time, .bz_comment_number, |
| 187 | +.bz_private_checkbox, .bz_comment_actions |
| 188 | +{ |
| 189 | + margin: 0 .5em; |
| 190 | +} |
| 191 | + |
| 192 | +.bz_comment_actions, .bz_comment_number, .bz_private_checkbox { |
| 193 | + float: right; |
| 194 | +} |
| 195 | + |
| 196 | +.bz_collapse_comment { |
| 197 | + text-decoration: none; |
| 198 | +} |
| 199 | + |
| 200 | +.bz_private_checkbox input { |
| 201 | + margin: 0; |
| 202 | + vertical-align: middle; |
| 203 | +} |
| 204 | + |
| 205 | +.bz_comment_head, .bz_first_comment_head { |
| 206 | + padding-top: .1em; |
| 207 | + padding-bottom: .1em; |
| 208 | + padding-left: .5em; |
| 209 | + background-color: #e0e0e0; |
| 210 | +} |
| 211 | + |
| 212 | +.bz_comment_user_images img { |
| 213 | + vertical-align: bottom; |
| 214 | +} |
| 215 | + |
| 216 | +.bz_comment_hilite pre { |
| 217 | + background-color: lightgreen; |
| 218 | + margin: 0; |
| 219 | + padding: 1em 0; |
| 220 | +} |
| 221 | + |
| 222 | +/** End Comments **/ |
| 223 | + |
| 224 | +.bz_default_hidden, .bz_tui_hidden, .bz_hidden_field, .bz_hidden_option { |
| 225 | + /* We have !important because we want elements with these classes to always |
| 226 | + * be hidden, even if there is some CSS that overrides it (we use these |
| 227 | + * classes inside JavaScript to hide things). */ |
| 228 | + display: none !important; |
| 229 | +} |
| 230 | + |
| 231 | +span.quote { |
| 232 | + color: #65379c; |
| 233 | + /* Make quoted text not wrap. */ |
| 234 | + white-space: pre; |
| 235 | +} |
| 236 | + |
| 237 | +table#flags th, |
| 238 | +table#flags td { |
| 239 | + vertical-align: middle; |
| 240 | + text-align: left; |
| 241 | +} |
| 242 | + |
| 243 | +.flag_select { |
| 244 | + min-width: 3em; |
| 245 | +} |
| 246 | + |
| 247 | +#error_msg { |
| 248 | + font-size: x-large; |
| 249 | +} |
| 250 | + |
| 251 | +.throw_error { |
| 252 | + background-color: #ff0000; |
| 253 | + color: black; |
| 254 | + font-size: 120%; |
| 255 | + margin: 1em; |
| 256 | + padding: 0.5em 1em; |
| 257 | +} |
| 258 | + |
| 259 | +dt { |
| 260 | + font-weight: bolder; |
| 261 | +} |
| 262 | +body > dl > dt { |
| 263 | + border-top: dotted gray thin; |
| 264 | +} |
| 265 | +dl dl > dt { |
| 266 | + border-top: none; |
| 267 | +} |
| 268 | + |
| 269 | +#admin_table th { |
| 270 | + white-space: normal !important; |
| 271 | +} |
| 272 | + |
| 273 | +/* Style of the attachment table and time tracking table */ |
| 274 | +#attachment_table { |
| 275 | + border-collapse: collapse; |
| 276 | + border: 1px solid silver !important; |
| 277 | + width: 52em; |
| 278 | +} |
| 279 | + |
| 280 | +table.bz_time_tracking_table { |
| 281 | + padding: 0.3em 0.3em 0.3em 0.5em; |
| 282 | +} |
| 283 | +#attachment_table th, .bz_attach_footer, .bz_time_tracking_table th { |
| 284 | + background-color: #E0E0E0; |
| 285 | + color: black; |
| 286 | +} |
| 287 | + |
| 288 | +#attachment_table td, .bz_time_tracking_table th, .bz_time_tracking_table td { |
| 289 | + border: 1px solid #333333; |
| 290 | +} |
| 291 | + |
| 292 | +.bz_attach_extra_info { |
| 293 | + font-size: smaller; |
| 294 | +} |
| 295 | + |
| 296 | +.bz_attach_flags, .bz_attach_footer { |
| 297 | + white-space: nowrap; |
| 298 | +} |
| 299 | + |
| 300 | +.bz_attach_view_hide { |
| 301 | + float: right; |
| 302 | + padding-left: 1em; |
| 303 | +} |
| 304 | + |
| 305 | +table.attachment_info th { |
| 306 | + text-align: right; |
| 307 | + vertical-align: top; |
| 308 | +} |
| 309 | + |
| 310 | +table.attachment_info td { |
| 311 | + text-align: left; |
| 312 | + vertical-align: top; |
| 313 | +} |
| 314 | + |
| 315 | +/* Text displayed when the attachment is not viewable by the web browser */ |
| 316 | +#noview { |
| 317 | + text-align: left; |
| 318 | + vertical-align: middle; |
| 319 | +} |
| 320 | + |
| 321 | +/* For bug fields */ |
| 322 | +.uneditable_textarea { |
| 323 | + width: 30em; |
| 324 | + font-size: medium; |
| 325 | +} |
| 326 | + |
| 327 | +div.user_match { |
| 328 | + margin-bottom: 1em; |
| 329 | +} |
| 330 | + |
| 331 | +.box { |
| 332 | + border: 1px solid black; |
| 333 | + color: black; |
| 334 | + background-color: #ffc; |
| 335 | + margin: 1em; |
| 336 | + padding: 0.5em 1em; |
| 337 | +} |
| 338 | + |
| 339 | +.collapsed { |
| 340 | + display: none; |
| 341 | +} |
| 342 | + |
| 343 | +/* Rules specific for printing */ |
| 344 | +@media print { |
| 345 | + #header, #footer { |
| 346 | + display: none; |
| 347 | + } |
| 348 | + |
| 349 | + body { |
| 350 | + background-image: none; |
| 351 | + background-color: #fff; |
| 352 | + } |
| 353 | +} |
| 354 | + |
| 355 | +.field_label { |
| 356 | + text-align: right; |
| 357 | + vertical-align: top; |
| 358 | + font-weight: bold; |
| 359 | + white-space: nowrap; |
| 360 | +} |
| 361 | + |
| 362 | +.field_value, form#Create th, form#Create td { |
| 363 | + vertical-align: top; |
| 364 | +} |
| 365 | + |
| 366 | +.calendar_button { |
| 367 | + background: transparent url("global/calendar.png") no-repeat; |
| 368 | + width: 20px; |
| 369 | + height: 20px; |
| 370 | + vertical-align: middle; |
| 371 | +} |
| 372 | +.calendar_button span { display: none } |
| 373 | +/* These classes are set by YUI. */ |
| 374 | +.yui-calcontainer { |
| 375 | + display: none; |
| 376 | + background-color: white; |
| 377 | + padding: 10px; |
| 378 | + border: 1px solid #404D6C; |
| 379 | +} |
| 380 | + |
| 381 | +.bug_urls { |
| 382 | + margin: 0 0 1em 0; |
| 383 | + padding: 0; |
| 384 | + list-style-type: none; |
| 385 | +} |
| 386 | + |
| 387 | +form#Create th { |
| 388 | + text-align: right; |
| 389 | +} |
| 390 | + |
| 391 | +form#Create .comment { |
| 392 | + vertical-align: top; |
| 393 | + overflow: auto; |
| 394 | + color: green; |
| 395 | + margin: 0 0.5em; |
| 396 | + padding: 0.3em; |
| 397 | + height: 8ex; |
| 398 | +} |
| 399 | + |
| 400 | +.image_button { |
| 401 | + background-repeat: no-repeat; |
| 402 | + background-position: center center; |
| 403 | + width: 30px; |
| 404 | + height: 20px; |
| 405 | +} |
| 406 | + |
| 407 | +#select_button { |
| 408 | + background-image: url(global/right.png); |
| 409 | +} |
| 410 | + |
| 411 | +#deselect_button { |
| 412 | + background-image: url(global/left.png); |
| 413 | +} |
| 414 | + |
| 415 | +#up_button { |
| 416 | + background-image: url(global/up.png); |
| 417 | +} |
| 418 | + |
| 419 | +#down_button { |
| 420 | + background-image: url(global/down.png); |
| 421 | +} |
| 422 | +.bz_emailprefs tr.bz_row_odd { |
| 423 | + background-color: #f0f0f0; |
| 424 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 425 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/vector.css |
— | — | @@ -0,0 +1,518 @@ |
| 2 | +/* Framework */ |
| 3 | +html, |
| 4 | +body { |
| 5 | + height: 100%; |
| 6 | + margin: 0; |
| 7 | + padding: 0; |
| 8 | + font-family: sans-serif; |
| 9 | + font-size: 1em; |
| 10 | +} |
| 11 | +body { |
| 12 | + background-color: #f3f3f3; |
| 13 | + background-image: url(images/page-base.png); |
| 14 | +} |
| 15 | +/* Content */ |
| 16 | +#content-container { |
| 17 | + margin-left: 10em; |
| 18 | + padding: 1em; |
| 19 | + background-image: url(images/border.png); |
| 20 | + background-position: top left; |
| 21 | + background-repeat: repeat-y; |
| 22 | + background-color: white; |
| 23 | +} |
| 24 | +/* Head */ |
| 25 | +#page-base { |
| 26 | + height: 2.5em; |
| 27 | + background-color: white; |
| 28 | + background-image: url(images/page-fade.png); |
| 29 | + background-position: bottom left; |
| 30 | + background-repeat: repeat-x; |
| 31 | +} |
| 32 | +#head-base { |
| 33 | + margin-top: -2.5em; |
| 34 | + margin-left: 10em; |
| 35 | + height: 2.5em; |
| 36 | + background-image: url(images/border.png); |
| 37 | + background-position: bottom left; |
| 38 | + background-repeat: repeat-x; |
| 39 | +} |
| 40 | +#head { |
| 41 | + position: absolute; |
| 42 | + top: 0; |
| 43 | + right: 0; |
| 44 | + width: 100%; |
| 45 | +} |
| 46 | +#head h5 { |
| 47 | + margin: 0; |
| 48 | + padding: 0; |
| 49 | +} |
| 50 | + /* Hide empty portlets */ |
| 51 | + div.emptyPortlet { |
| 52 | + display: none; |
| 53 | + } |
| 54 | + /* Personal */ |
| 55 | + #p-personal #mini_login_container .mini_login { |
| 56 | + margin-left:-6px; |
| 57 | + margin-right:6px; |
| 58 | + margin-top:-5px; |
| 59 | + margin-bottom:-1px; |
| 60 | + } |
| 61 | + #p-personal #forgot_container .mini_forgot { |
| 62 | + margin-left:-6px; |
| 63 | + margin-right:6px; |
| 64 | + margin-top:-5px; |
| 65 | + margin-bottom:-1px; |
| 66 | + padding-left: 1.5em; |
| 67 | + } |
| 68 | + #p-personal { |
| 69 | + margin-top: 0.5em; |
| 70 | + margin-right: 1em; |
| 71 | + float: right; |
| 72 | + } |
| 73 | + #p-personal h5 { |
| 74 | + display: none; |
| 75 | + } |
| 76 | + #p-personal ul { |
| 77 | + list-style: none; |
| 78 | + margin: 0; |
| 79 | + padding: 0; |
| 80 | + } |
| 81 | + #p-personal li { |
| 82 | + line-height: 1.125em; |
| 83 | + float: left; |
| 84 | + } |
| 85 | + #p-personal li { |
| 86 | + margin-left: 0.75em; |
| 87 | + margin-top: 0.5em; |
| 88 | + font-size: 0.75em; |
| 89 | + } |
| 90 | + /* Search */ |
| 91 | + #p-search h5 { |
| 92 | + display: none; |
| 93 | + } |
| 94 | + #p-search { |
| 95 | + float: right; |
| 96 | + } |
| 97 | + #p-search { |
| 98 | + margin-right: 0.5em; |
| 99 | + margin-left: 0.5em; |
| 100 | + } |
| 101 | + #p-search form, |
| 102 | + #p-search input { |
| 103 | + margin: 0; |
| 104 | + margin-top: 0.4em; |
| 105 | + } |
| 106 | + #simpleSearch { |
| 107 | + margin-top: 0.5em; |
| 108 | + position: relative; |
| 109 | + border: solid 1px #AAAAAA; |
| 110 | + background-color: white; |
| 111 | + background-image: url(images/search-fade.png); |
| 112 | + background-position: top left; |
| 113 | + background-repeat: repeat-x; |
| 114 | + } |
| 115 | + #simpleSearch label { |
| 116 | + font-size: 0.8em; |
| 117 | + top: 0.25em; |
| 118 | + } |
| 119 | + #simpleSearch input#searchInput { |
| 120 | + margin: 0; |
| 121 | + border-width: 0; |
| 122 | + padding: 0.25em; |
| 123 | + line-height: 1em; |
| 124 | + font-size: 0.8em; |
| 125 | + width: 9em; |
| 126 | + background-color: transparent; |
| 127 | + } |
| 128 | + /* OVERRIDDEN BY COMPLIANT BROWSERS */ |
| 129 | + #simpleSearch button#searchButton { |
| 130 | + margin: 0; |
| 131 | + padding: 0; |
| 132 | + width: 1.75em; |
| 133 | + height: 1.5em; |
| 134 | + border: none; |
| 135 | + cursor: pointer; |
| 136 | + background-color: transparent; |
| 137 | + background-image: url(images/search-ltr.png); |
| 138 | + background-position: center center; |
| 139 | + background-repeat: no-repeat; |
| 140 | + } |
| 141 | + /* IGNORED BY IE6 */ |
| 142 | + #simpleSearch > button#searchButton { |
| 143 | + height: 100%; |
| 144 | + } |
| 145 | + |
| 146 | + form.mini_login input.bz_login { |
| 147 | + width: 10em; |
| 148 | + } |
| 149 | + form.mini_login input.bz_password { |
| 150 | + width: 6em; |
| 151 | + } |
| 152 | + form.mini_login input.bz_remember { |
| 153 | + margin: 0; |
| 154 | + } |
| 155 | + .bz_default_hidden { |
| 156 | + display: none !important; |
| 157 | + } |
| 158 | + |
| 159 | + |
| 160 | +/* Panel */ |
| 161 | +#panel { |
| 162 | + position: absolute; |
| 163 | + top: 160px; |
| 164 | + padding-top: 1em; |
| 165 | + width: 10em; |
| 166 | + left: 0; |
| 167 | +} |
| 168 | + #panel div.portal { |
| 169 | + padding-bottom: 1.5em; |
| 170 | + } |
| 171 | + #panel div.portal h5 { |
| 172 | + font-weight: normal; |
| 173 | + color: #444444; |
| 174 | + padding: 0.25em; |
| 175 | + padding-top: 0; |
| 176 | + padding-left: 1.75em; |
| 177 | + margin: 0.25em 0; |
| 178 | + cursor: default; |
| 179 | + border: none; |
| 180 | + font-size: 0.75em; |
| 181 | + } |
| 182 | + #panel div.portal div.body { |
| 183 | + margin: 0; |
| 184 | + padding-top: 0.5em; |
| 185 | + margin-left: 1.25em; |
| 186 | + background-image: url(images/portal-break.png); |
| 187 | + background-repeat: no-repeat; |
| 188 | + background-position: top left; |
| 189 | + } |
| 190 | + #panel div.portal div.body ul { |
| 191 | + list-style: none; |
| 192 | + list-style-image: none; |
| 193 | + list-style-type: none; |
| 194 | + padding: 0; |
| 195 | + margin: 0; |
| 196 | + } |
| 197 | + #panel div.portal div.body ul li { |
| 198 | + line-height: 1.125em; |
| 199 | + padding: 0; |
| 200 | + padding-bottom: 0.5em; |
| 201 | + margin: 0; |
| 202 | + overflow: hidden; |
| 203 | + font-size: 0.75em; |
| 204 | + } |
| 205 | + #panel div.portal div.body ul li a { |
| 206 | + color: #0645ad; |
| 207 | + } |
| 208 | + #panel div.portal div.body ul li a:visited { |
| 209 | + color: #0b0080; |
| 210 | + } |
| 211 | +/* Footer */ |
| 212 | +#footer { |
| 213 | + margin-left: 10em; |
| 214 | + margin-top: 0; |
| 215 | + padding: 0.75em; |
| 216 | + background-image: url(images/border.png); |
| 217 | + background-position: top left; |
| 218 | + background-repeat: repeat-x; |
| 219 | +} |
| 220 | +#footer ul { |
| 221 | + list-style: none; |
| 222 | + list-style-image: none; |
| 223 | + list-style-type: none; |
| 224 | + margin: 0; |
| 225 | + padding: 0; |
| 226 | +} |
| 227 | +#footer ul li { |
| 228 | + margin: 0; |
| 229 | + padding: 0; |
| 230 | + padding-top: 0.5em; |
| 231 | + padding-bottom: 0.5em; |
| 232 | + color: #333333; |
| 233 | + font-size: 0.7em; |
| 234 | +} |
| 235 | +#footer #footer-icons { |
| 236 | + float: right; |
| 237 | +} |
| 238 | +#footer #footer-places { |
| 239 | + float: left; |
| 240 | +} |
| 241 | +#footer #footer-info li { |
| 242 | + line-height: 1.4em; |
| 243 | +} |
| 244 | +#footer #footer-icons li { |
| 245 | + float: left; |
| 246 | + margin-left: 0.5em; |
| 247 | + line-height: 2em; |
| 248 | +} |
| 249 | +#footer #footer-places li { |
| 250 | + float: left; |
| 251 | + margin-right: 1em; |
| 252 | + line-height: 2em; |
| 253 | +} |
| 254 | +/* Logo */ |
| 255 | +#p-logo { |
| 256 | + position: absolute; |
| 257 | + top: -160px; |
| 258 | + left: 0; |
| 259 | + width: 10em; |
| 260 | + height: 160px; |
| 261 | +} |
| 262 | +#p-logo a { |
| 263 | + display: block; |
| 264 | + width: 10em; |
| 265 | + height: 160px; |
| 266 | + background-repeat: no-repeat; |
| 267 | + background-position: center center; |
| 268 | + text-decoration: none; |
| 269 | +} |
| 270 | + |
| 271 | + |
| 272 | +/* tabs (begin) */ |
| 273 | +div.tabbed { |
| 274 | + background-color:#F9F9F9; |
| 275 | + background-image:url(images/preferences-base.png); |
| 276 | + #border: solid #CCCCCC; |
| 277 | + #border-width: 0 1px 1px 1px; |
| 278 | + clear:both; |
| 279 | + width:100%; |
| 280 | + margin: 2.25em 0 0 0; |
| 281 | +} |
| 282 | + |
| 283 | + div.tabbody { |
| 284 | + padding: 1em 1em 1em 1em; |
| 285 | + border: solid #CCCCCC; |
| 286 | + border-width: 1px; |
| 287 | +} |
| 288 | +div.tabbody table td, div.tabbody table th, #bodyContent form table td, #bodyContent form table th { |
| 289 | + border:none !important; |
| 290 | + padding: 0.15em 0.25em; |
| 291 | + line-height: 1.75em; |
| 292 | +} |
| 293 | +table.tabs { |
| 294 | + position:absolute; |
| 295 | + width:auto; |
| 296 | + background-image:url(images/preferences-break.png); |
| 297 | + background-position:left bottom; |
| 298 | + background-repeat:no-repeat; |
| 299 | + margin: -2.25em 0 0 0; |
| 300 | + padding-left: 1px; |
| 301 | +} |
| 302 | +.tabs tbody { |
| 303 | + background-image:url(images/preferences-fade.png); |
| 304 | + background-position:left bottom; |
| 305 | + background-repeat:repeat-x; |
| 306 | +} |
| 307 | + |
| 308 | +.tabs td { |
| 309 | + width: auto; |
| 310 | + line-height:1.5em; |
| 311 | + background-image:url(images/preferences-break.png); |
| 312 | + background-color: white; |
| 313 | + background-position:right bottom; |
| 314 | + background-repeat:no-repeat; |
| 315 | + border: solid #CCCCCC; |
| 316 | + border-width: 0 0 1px 0; |
| 317 | + text-align: center; |
| 318 | + margin:0; |
| 319 | + padding:0 .75em 3px .75em; |
| 320 | + white-space:nowrap; |
| 321 | + font-size: 0.9em; |
| 322 | +} |
| 323 | +.tabs td a { |
| 324 | + background-image:none; |
| 325 | + color:#0645AD; |
| 326 | + display:inline-block; |
| 327 | + position:relative; |
| 328 | + line-height: 2.25em; |
| 329 | +} |
| 330 | +.tabs td.selected { |
| 331 | + background-color:transparent; |
| 332 | + color:#333333; |
| 333 | + border-width: 0; |
| 334 | + text-decoration:none; |
| 335 | +} |
| 336 | +.tabs td.spacer { |
| 337 | + display: none; |
| 338 | +} |
| 339 | +/* tabs (end) */ |
| 340 | + |
| 341 | +/* Content */ |
| 342 | +#content-container { |
| 343 | + line-height: 1.5em; |
| 344 | +} |
| 345 | +#bodyContent { |
| 346 | + font-size: 0.8em; |
| 347 | + position: relative; |
| 348 | + width: 100%; |
| 349 | + line-height: 1.5em; |
| 350 | +} |
| 351 | +#bodyContent table { |
| 352 | + font-size: 100%; |
| 353 | + border: none; |
| 354 | +} |
| 355 | +#bodyContent td, #bodyContent th { |
| 356 | + border: none; |
| 357 | +} |
| 358 | +/* Links */ |
| 359 | +a { |
| 360 | + text-decoration: none; |
| 361 | + color: #0645ad; |
| 362 | + background: none; |
| 363 | +} |
| 364 | +a:visited { |
| 365 | + color: #0b0080; |
| 366 | +} |
| 367 | +a:active { |
| 368 | + color: #faa700; |
| 369 | +} |
| 370 | +a:hover { |
| 371 | + text-decoration: underline; |
| 372 | +} |
| 373 | +a.stub { |
| 374 | + color: #772233; |
| 375 | +} |
| 376 | +a.new, |
| 377 | +#p-personal a.new { |
| 378 | + color: #ba0000; |
| 379 | +} |
| 380 | +a.new:visited, |
| 381 | +#p-personal a.new:visited { |
| 382 | + color: #a55858; |
| 383 | +} |
| 384 | +/* Inline Elements */ |
| 385 | +img { |
| 386 | + border: none; |
| 387 | + vertical-align: middle; |
| 388 | +} |
| 389 | +hr { |
| 390 | + height: 1px; |
| 391 | + color: #aaa; |
| 392 | + background-color: #aaa; |
| 393 | + border: 0; |
| 394 | + margin: .2em 0 .2em 0; |
| 395 | +} |
| 396 | +/* Structural Elements */ |
| 397 | +p { |
| 398 | + margin: .4em 0 .5em 0; |
| 399 | + line-height: 1.5em; |
| 400 | +} |
| 401 | +abbr, |
| 402 | +acronym { |
| 403 | + border-bottom: 1px dotted black; |
| 404 | + color: black; |
| 405 | + background: none; |
| 406 | + cursor: help; |
| 407 | +} |
| 408 | +q { |
| 409 | + font-family: Times, "Times New Roman", serif; |
| 410 | + font-style: italic; |
| 411 | +} |
| 412 | +code { |
| 413 | + background-color: #f9f9f9; |
| 414 | +} |
| 415 | +pre { |
| 416 | + padding: 1em; |
| 417 | + border: 1px dashed #2f6fab; |
| 418 | + color: black; |
| 419 | + background-color: #f9f9f9; |
| 420 | + line-height: 1.1em; |
| 421 | +} |
| 422 | +tbody.file pre { |
| 423 | + padding: 0; |
| 424 | + border: 0; |
| 425 | + background: transparent; |
| 426 | + } |
| 427 | +ul { |
| 428 | + line-height: 1.5em; |
| 429 | + list-style-type: square; |
| 430 | + margin: .3em 0 0 1.5em; |
| 431 | + padding: 0; |
| 432 | + list-style-image: url(images/bullet-icon.png); |
| 433 | +} |
| 434 | +ol { |
| 435 | + line-height: 1.5em; |
| 436 | + margin: .3em 0 0 3.2em; |
| 437 | + padding: 0; |
| 438 | + list-style-image: none; |
| 439 | +} |
| 440 | +li { |
| 441 | + margin-bottom: .1em; |
| 442 | +} |
| 443 | +dt { |
| 444 | + font-weight: bold; |
| 445 | + margin-bottom: .1em; |
| 446 | +} |
| 447 | +dl { |
| 448 | + margin-top: .2em; |
| 449 | + margin-bottom: .5em; |
| 450 | +} |
| 451 | +dd { |
| 452 | + line-height: 1.5em; |
| 453 | + margin-left: 2em; |
| 454 | + margin-bottom: .1em; |
| 455 | +} |
| 456 | +#content-container a.external, |
| 457 | +#content-container a[href ^="gopher://"] { |
| 458 | + background: url(images/external-link-ltr-icon.png) center right no-repeat; |
| 459 | + padding: 0 13px 0 0; |
| 460 | +} |
| 461 | +#content-container a[href ^="https://"], |
| 462 | +.link-https { |
| 463 | + background: url(images/lock-icon.png) center right no-repeat; |
| 464 | + padding: 0 18px 0 0; |
| 465 | +} |
| 466 | +#content-container a[href ^="mailto:"], |
| 467 | +.link-mailto { |
| 468 | + background: url(images/mail-icon.png) center right no-repeat; |
| 469 | + padding: 0 18px 0 0; |
| 470 | +} |
| 471 | +#content-container a[href ^="news://"] { |
| 472 | + background: url(images/news-icon.png) center right no-repeat; |
| 473 | + padding: 0 18px 0 0; |
| 474 | +} |
| 475 | +#content-container a[href ^="ftp://"], |
| 476 | +.link-ftp { |
| 477 | + background: url(images/file-icon.png) center right no-repeat; |
| 478 | + padding: 0 18px 0 0; |
| 479 | +} |
| 480 | +#content-container a[href ^="irc://"], |
| 481 | +#content-container a.extiw[href ^="irc://"], |
| 482 | +.link-irc { |
| 483 | + background: url(images/talk-icon.png) center right no-repeat; |
| 484 | + padding: 0 18px 0 0; |
| 485 | +} |
| 486 | +#content-container a.external[href $=".ogg"], #content-container a.external[href $=".OGG"], |
| 487 | +#content-container a.external[href $=".mid"], #content-container a.external[href $=".MID"], |
| 488 | +#content-container a.external[href $=".midi"], #content-container a.external[href $=".MIDI"], |
| 489 | +#content-container a.external[href $=".mp3"], #content-container a.external[href $=".MP3"], |
| 490 | +#content-container a.external[href $=".wav"], #content-container a.external[href $=".WAV"], |
| 491 | +#content-container a.external[href $=".wma"], #content-container a.external[href $=".WMA"], |
| 492 | +.link-audio { |
| 493 | + background: url("images/audio-icon.png") center right no-repeat; |
| 494 | + padding: 0 18px 0 0; |
| 495 | +} |
| 496 | +#content-container a.external[href $=".ogm"], #content-container a.external[href $=".OGM"], |
| 497 | +#content-container a.external[href $=".avi"], #content-container a.external[href $=".AVI"], |
| 498 | +#content-container a.external[href $=".mpeg"], #content-container a.external[href $=".MPEG"], |
| 499 | +#content-container a.external[href $=".mpg"], #content-container a.external[href $=".MPG"], |
| 500 | +.link-video { |
| 501 | + background: url("images/video-icon.png") center right no-repeat; |
| 502 | + padding: 0 18px 0 0; |
| 503 | +} |
| 504 | +#content-container a.external[href $=".pdf"], #content-container a.external[href $=".PDF"], |
| 505 | +#content-container a.external[href *=".pdf#"], #content-container a.external[href *=".PDF#"], |
| 506 | +#content-container a.external[href *=".pdf?"], #content-container a.external[href *=".PDF?"], |
| 507 | +.link-document { |
| 508 | + background: url("images/document-icon.png") center right no-repeat; |
| 509 | + padding: 0 18px 0 0; |
| 510 | +} |
| 511 | +#content-container a.external { |
| 512 | + color: #36b; |
| 513 | +} |
| 514 | +/* Icon for Usernames */ |
| 515 | +.user-link { |
| 516 | + background: url(images/user-icon.png) left top no-repeat; |
| 517 | + padding-left: 15px !important; |
| 518 | + text-transform: none; |
| 519 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/vector.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 520 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/skins.tgz |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/skins.tgz |
___________________________________________________________________ |
Added: svn:mime-type |
2 | 521 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/voting.css |
— | — | @@ -0,0 +1,24 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Gavin Shelley <bugzilla@chimpychompy.org> |
| 15 | + */ |
| 16 | + |
| 17 | +/* Highlight the row for the bug being voted on */ |
| 18 | +tr.bz_bug_being_voted_on { |
| 19 | + background-color: #e2e2e2; |
| 20 | +} |
| 21 | + |
| 22 | +tr.bz_bug_being_voted_on td { |
| 23 | + border-style: solid none solid none; |
| 24 | + border-width: thin; |
| 25 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/voting.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 26 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/release-notes.css |
— | — | @@ -0,0 +1,35 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Initial Developer of the Original Code is Everything Solved. |
| 13 | + * Portions created by Everything Solved are Copyright (C) 2006 |
| 14 | + * Everything Solved. All Rights Reserved. |
| 15 | + * |
| 16 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 17 | + * |
| 18 | + * Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> |
| 19 | + */ |
| 20 | + |
| 21 | +#bugzilla-body { |
| 22 | + padding: 0 1em; |
| 23 | +} |
| 24 | + |
| 25 | +.req_new { |
| 26 | + color: red; |
| 27 | +} |
| 28 | + |
| 29 | +.req_table { |
| 30 | + border-collapse: collapse; |
| 31 | +} |
| 32 | + |
| 33 | +.req_table td, .req_table th { |
| 34 | + border: 1px solid black; |
| 35 | + padding: .25em; |
| 36 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/release-notes.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 37 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/editusers.css |
— | — | @@ -0,0 +1,71 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Marc Schumann <wurblzap@gmail.com> |
| 15 | + */ |
| 16 | + |
| 17 | +table.main { |
| 18 | + border-spacing: 1em; |
| 19 | +} |
| 20 | +table.main tr { |
| 21 | + vertical-align: top; |
| 22 | + border-top: solid thin black; |
| 23 | +} |
| 24 | +table.main th { |
| 25 | + text-align: right; |
| 26 | + white-space: nowrap; |
| 27 | +} |
| 28 | +table.main th, |
| 29 | +table.main td { |
| 30 | + padding: 0; |
| 31 | +} |
| 32 | +table.main ul { |
| 33 | + list-style-type: none; |
| 34 | + padding-left: 0 |
| 35 | +} |
| 36 | + |
| 37 | +table.groups { |
| 38 | + border-spacing: 1px; |
| 39 | +} |
| 40 | +table.groups tr.indirect { |
| 41 | + background-color: #cccccc; |
| 42 | +} |
| 43 | +table.groups th { |
| 44 | + text-align: left; |
| 45 | + padding: 0 0 0 1ex; |
| 46 | +} |
| 47 | +table.groups td { |
| 48 | + padding: 2px; |
| 49 | +} |
| 50 | +table.groups td.checkbox { |
| 51 | + text-align: center; |
| 52 | + white-space: nowrap; |
| 53 | +} |
| 54 | + |
| 55 | +table#user_responsibilities th { |
| 56 | + text-align: center; |
| 57 | + padding: 0 1em 1em; |
| 58 | +} |
| 59 | + |
| 60 | +table#user_responsibilities th.product { |
| 61 | + text-align: left; |
| 62 | + padding: 1em 0 0; |
| 63 | +} |
| 64 | + |
| 65 | +table#user_responsibilities td.center { |
| 66 | + text-align: center; |
| 67 | +} |
| 68 | + |
| 69 | +.missing { |
| 70 | + color: red; |
| 71 | + border-color: inherit; |
| 72 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/editusers.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 73 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/index.css |
— | — | @@ -0,0 +1,134 @@ |
| 2 | + /* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Vitaly Harisov <vitaly@rathedg.com> |
| 15 | + * Guy Pyrzak <guy.pyrzak@gmail.com> |
| 16 | + */ |
| 17 | + |
| 18 | +/* index page (begin) */ |
| 19 | + |
| 20 | + #page-index |
| 21 | + { |
| 22 | + padding: 0.2em 0.2em 0.15em 0.2em; |
| 23 | + } |
| 24 | + |
| 25 | + /* By default these contain nothing, but these CSS rules make things |
| 26 | + easier on customizers. */ |
| 27 | + .intro, .outro { |
| 28 | + text-align: center; |
| 29 | + float: left; |
| 30 | + padding: 0 2em 2em 2em; |
| 31 | + } |
| 32 | + |
| 33 | + /* Hide from NN4 */ |
| 34 | + |
| 35 | + #new_release |
| 36 | + { |
| 37 | + border: 2px solid red; |
| 38 | + padding: 0.5em 1em; |
| 39 | + margin: 1em; |
| 40 | + font-weight: bold; |
| 41 | + } |
| 42 | + |
| 43 | + #new_release .notice |
| 44 | + { |
| 45 | + font-size: 80%; |
| 46 | + font-weight: normal; |
| 47 | + } |
| 48 | + |
| 49 | + #welcome-admin a |
| 50 | + { |
| 51 | + font-weight: bold; |
| 52 | + } |
| 53 | + |
| 54 | + .bz_common_actions { |
| 55 | + display: block; |
| 56 | + height: 190px; |
| 57 | + width: 195px; |
| 58 | + float: left; |
| 59 | + margin: 0 3ex 3em 0; |
| 60 | + text-align: center; |
| 61 | + } |
| 62 | + .bz_common_actions span { |
| 63 | + position: relative; |
| 64 | + top: 95%; |
| 65 | + font-weight: bold; |
| 66 | + } |
| 67 | + |
| 68 | + .bz_common_actions, |
| 69 | + .bz_common_actions:visited, |
| 70 | + .bz_common_actions:hover |
| 71 | + { |
| 72 | + text-decoration: none; |
| 73 | + } |
| 74 | + |
| 75 | + #enter_bug { background: url(index/bug.gif) no-repeat; } |
| 76 | + #query { background: url(index/search.gif) no-repeat; } |
| 77 | + #account { background: url(index/account.gif) no-repeat; } |
| 78 | + |
| 79 | + #quicksearchForm |
| 80 | + { |
| 81 | + clear: both; |
| 82 | + text-align: center; |
| 83 | + margin-bottom: 2em; |
| 84 | + } |
| 85 | + |
| 86 | + #quicksearchForm #quicksearch_main |
| 87 | + { |
| 88 | + width: 25em; |
| 89 | + } |
| 90 | + |
| 91 | + #quicksearchForm |
| 92 | + { |
| 93 | + margin: 0; |
| 94 | + padding: 0; |
| 95 | + } |
| 96 | + |
| 97 | + #page-index table{ |
| 98 | + border-collapse: collapse; |
| 99 | + } |
| 100 | + |
| 101 | + #welcome |
| 102 | + { |
| 103 | + font-size: x-large; |
| 104 | + font-weight: bold; |
| 105 | + text-align: center; |
| 106 | + margin: 0 0 0.8em 0; |
| 107 | + padding: 0; |
| 108 | + } |
| 109 | + |
| 110 | + ul.additional_links |
| 111 | + { |
| 112 | + list-style: none; |
| 113 | + margin: 0; |
| 114 | + padding: 0; |
| 115 | + } |
| 116 | + |
| 117 | + ul#quicksearch_links{ |
| 118 | + margin-bottom: 1em; |
| 119 | + } |
| 120 | + |
| 121 | + ul.additional_links li |
| 122 | + { |
| 123 | + display: inline; |
| 124 | + } |
| 125 | + |
| 126 | + ul.additional_links li.bz_default_hidden |
| 127 | + { |
| 128 | + display: none; |
| 129 | + } |
| 130 | + |
| 131 | + input.quicksearch_help_text |
| 132 | + { |
| 133 | + color: #ccc; |
| 134 | + } |
| 135 | +/* index page (end) */ |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/index.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 136 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/summarize-time.css |
— | — | @@ -0,0 +1,46 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Christian Reis <kiko@async.com.br> |
| 15 | + */ |
| 16 | + |
| 17 | +td { vertical-align: top } |
| 18 | + |
| 19 | +table.zeroitems, table.realitems { |
| 20 | + margin-left: 2.0em; |
| 21 | + margin-top: 2px; |
| 22 | + border: 1px solid black; |
| 23 | + border: 1px solid black; |
| 24 | +} |
| 25 | + |
| 26 | +tr.section_total { |
| 27 | + background: #000000; |
| 28 | + color: #ffffff; |
| 29 | +} |
| 30 | + |
| 31 | +td.subtotal { |
| 32 | + background: #B0C0D9; |
| 33 | +} |
| 34 | + |
| 35 | +.zeroitems .bug_header { background: #d0e0f0 } |
| 36 | +.zeroitems .bug_header2 { background: #f9f9f9 } |
| 37 | + |
| 38 | +/* the fixed headers -- .number uses bug_header so hack it here */ |
| 39 | +.number .bug_header, .number .bug_header2 { background: #d0e0f0 } |
| 40 | +.owner_header { background: #d0e0f0 } |
| 41 | + |
| 42 | + |
| 43 | +/* the details headers */ |
| 44 | +.number .owner_header, .owner .bug_header { background: #ffffff } |
| 45 | +.number .owner_header2, .owner .bug_header2 { background: #EFEFEF } |
| 46 | + |
| 47 | + |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/summarize-time.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 48 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/buglist.css |
— | — | @@ -0,0 +1,49 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * The Initial Developer of the Original Code is Mike Schrag. |
| 15 | + * Portions created by Marc Schumann are Copyright (c) 2007 Mike Schrag. |
| 16 | + * All rights reserved. |
| 17 | + * |
| 18 | + * Contributor(s): Mike Schrag <mschrag@pobox.com> |
| 19 | + * Byron Jones <bugzilla@glob.com.au> |
| 20 | + * Marc Schumann <wurblzap@gmail.com> |
| 21 | + */ |
| 22 | + |
| 23 | +table.bz_buglist td { |
| 24 | + padding: 0.5em 0.25em; |
| 25 | +} |
| 26 | +tr.bz_bugitem:hover { |
| 27 | + background-color: #f0f0f0; |
| 28 | +} |
| 29 | +/* Must go first because of issue with BugZilla wrongly assuming case sensitivity in CSS classes */ |
| 30 | +.bz_normal { |
| 31 | + color:#BB7700; |
| 32 | +} |
| 33 | +/* Otherwise, in order of severity */ |
| 34 | +.bz_enhancement { |
| 35 | + color:#106581; |
| 36 | +} |
| 37 | +.bz_trivial { |
| 38 | + color:#009966; |
| 39 | +} |
| 40 | +.bz_minor { |
| 41 | + color:#669900; |
| 42 | +} |
| 43 | +.bz_major { |
| 44 | + color:#D30000; |
| 45 | +} |
| 46 | +.bz_critical { |
| 47 | + color:#CC0000; |
| 48 | + font-weight:bold; |
| 49 | +} |
| 50 | + |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/buglist.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 51 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/body-back.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/body-back.gif |
___________________________________________________________________ |
Added: svn:mime-type |
2 | 52 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/right.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/right.png |
___________________________________________________________________ |
Added: svn:mime-type |
3 | 53 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/up.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/up.png |
___________________________________________________________________ |
Added: svn:mime-type |
4 | 54 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/down.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/down.png |
___________________________________________________________________ |
Added: svn:mime-type |
5 | 55 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/header.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/header.png |
___________________________________________________________________ |
Added: svn:mime-type |
6 | 56 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/calendar.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/calendar.png |
___________________________________________________________________ |
Added: svn:mime-type |
7 | 57 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/left.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/global/left.png |
___________________________________________________________________ |
Added: svn:mime-type |
8 | 58 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/IE-fixes.css |
— | — | @@ -0,0 +1,38 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Marc Schumann <wurblzap@gmail.com> |
| 15 | + */ |
| 16 | + |
| 17 | +.bz_comment_text, .uneditable_textarea { |
| 18 | + white-space: pre; |
| 19 | + word-wrap: break-word; |
| 20 | +} |
| 21 | + |
| 22 | +#footer #useful-links li { |
| 23 | + padding-bottom: 0.8ex; |
| 24 | +} |
| 25 | + |
| 26 | +#footer .label { |
| 27 | + display: block; |
| 28 | + float: left; |
| 29 | + width: 8.2em; |
| 30 | + padding-bottom: 0.1ex; |
| 31 | +} |
| 32 | + |
| 33 | +#footer #links-actions .label { |
| 34 | + padding-top: 0.35em; |
| 35 | +} |
| 36 | + |
| 37 | +#footer .links { |
| 38 | + display: inline; |
| 39 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/IE-fixes.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 40 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/dependency-tree.css |
— | — | @@ -0,0 +1,94 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * The Initial Developer of the Original Code is Netscape |
| 15 | + * Communications |
| 16 | + * Corporation. Portions created by Netscape are |
| 17 | + * Copyright (C) 1998 Netscape Communications Corporation. All |
| 18 | + * Rights Reserved. |
| 19 | + * |
| 20 | + * Contributor(s): Christian Reis <kiko@async.com.br> |
| 21 | + * Andr� Batosti <batosti@async.com.br> |
| 22 | + */ |
| 23 | + |
| 24 | +ul.tree { |
| 25 | + padding-left: 0em; |
| 26 | + margin-left: 1em; |
| 27 | + display: block; |
| 28 | +} |
| 29 | + |
| 30 | +ul.tree ul { |
| 31 | + padding-top: 3px; |
| 32 | + display: block; |
| 33 | +} |
| 34 | + |
| 35 | +ul.tree li { |
| 36 | + /* see http://www.kryogenix.org/code/browser/aqlists/ for idea */ |
| 37 | + padding-top: 3px; |
| 38 | + text-indent: -1.2em; |
| 39 | + padding-left: 0.5em; |
| 40 | + padding-bottom: 3px; |
| 41 | + list-style-type: none; |
| 42 | + background: url("dependency-tree/bug-item.png") no-repeat; |
| 43 | +} |
| 44 | + |
| 45 | +ul.tree li a.b { |
| 46 | + padding-left: 30px; |
| 47 | + margin-right: -14px; |
| 48 | + text-decoration: none; |
| 49 | +} |
| 50 | + |
| 51 | +ul.tree li a.b_open { |
| 52 | + background: url("dependency-tree/tree-open.png") center no-repeat; |
| 53 | + cursor: pointer; |
| 54 | +} |
| 55 | + |
| 56 | +ul.tree li a.b_closed { |
| 57 | + background: url("dependency-tree/tree-closed.png") center no-repeat; |
| 58 | + cursor: pointer; |
| 59 | +} |
| 60 | + |
| 61 | +ul.tree a.tree_link img { |
| 62 | + border: 0; |
| 63 | +} |
| 64 | + |
| 65 | +.summ_info { |
| 66 | + /* change to inline if you would like to see the full bug details |
| 67 | + * displayed in the list */ |
| 68 | + display: none; |
| 69 | + font-size: 75%; |
| 70 | +} |
| 71 | + |
| 72 | +.hint { |
| 73 | + font-size: 90%; |
| 74 | + margin: 0.2em; |
| 75 | + padding: 0.1em; |
| 76 | +} |
| 77 | + |
| 78 | +.hint h3, .hint ul { |
| 79 | + margin-top: 0.1em; |
| 80 | + margin-bottom: 0.1em; |
| 81 | +} |
| 82 | + |
| 83 | +.summ A, .summ_deep A { |
| 84 | + text-decoration: none; |
| 85 | + color: darkblue; |
| 86 | +} |
| 87 | + |
| 88 | +.summ_deep { |
| 89 | +} |
| 90 | + |
| 91 | +.summ_h A { |
| 92 | + background-color: #ffffaa; |
| 93 | + color: #333; |
| 94 | + font-weight: bold; |
| 95 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/dependency-tree.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 96 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/create_attachment.css |
— | — | @@ -0,0 +1,106 @@ |
| 2 | + /* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Myk Melez <myk@mozilla.org> |
| 15 | + * Joel Peshkin <bugreport@peshkin.net> |
| 16 | + * Erik Stambaugh <erik@dasbistro.com> |
| 17 | + * Marc Schumann <wurblzap@gmail.com> |
| 18 | + */ |
| 19 | + |
| 20 | +table.attachment_entry th { |
| 21 | + text-align: right; |
| 22 | + vertical-align: baseline; |
| 23 | + white-space: nowrap; |
| 24 | +} |
| 25 | + |
| 26 | +table.attachment_entry td { |
| 27 | + text-align: left; |
| 28 | + vertical-align: baseline; |
| 29 | + padding-bottom: 5px; |
| 30 | +} |
| 31 | + |
| 32 | +table#flags th, |
| 33 | +table#flags td { |
| 34 | + text-align: left; |
| 35 | + vertical-align: baseline; |
| 36 | + font-size: small; |
| 37 | +} |
| 38 | + |
| 39 | +/* Rules used to view patches in diff mode. */ |
| 40 | + |
| 41 | +.file_head { |
| 42 | + font-weight: bold; |
| 43 | + font-size: 1em; |
| 44 | + background-color: #c3c3c3; |
| 45 | + border: 1px solid black; |
| 46 | +} |
| 47 | + |
| 48 | +.file_head a { |
| 49 | + text-decoration: none; |
| 50 | + font-family: monospace; |
| 51 | + font-size: 1.1em; |
| 52 | +} |
| 53 | + |
| 54 | +.file_collapse { |
| 55 | + display: none; |
| 56 | +} |
| 57 | + |
| 58 | +.section_head { |
| 59 | + background-color: #f0f0f0; |
| 60 | + border: 1px solid black; |
| 61 | + text-align: left; |
| 62 | +} |
| 63 | + |
| 64 | +table.file_table { |
| 65 | + table-layout: fixed; |
| 66 | + width: 100%; |
| 67 | + empty-cells: show; |
| 68 | + border-spacing: 0px; |
| 69 | + border-collapse: collapse; |
| 70 | + /* draw border below last open context section in listing */ |
| 71 | + border-bottom: 1px solid black; |
| 72 | +} |
| 73 | + |
| 74 | +tbody.file pre { |
| 75 | + display: inline; |
| 76 | + white-space: pre-wrap; /* CSS 3 & CSS 2.1 */ |
| 77 | + white-space: -moz-pre-wrap; /* Gecko < 1.9.1 */ |
| 78 | + white-space: -o-pre-wrap; /* Opera 7 */ |
| 79 | + font-size: 0.9em; |
| 80 | +} |
| 81 | + |
| 82 | +tbody.file pre:empty { |
| 83 | + display: block; |
| 84 | +} |
| 85 | + |
| 86 | +.changed { |
| 87 | + background-color: lightblue; |
| 88 | +} |
| 89 | + |
| 90 | +.added { |
| 91 | + background-color: lightgreen; |
| 92 | +} |
| 93 | + |
| 94 | +.removed { |
| 95 | + background-color: #FFCC99; |
| 96 | +} |
| 97 | + |
| 98 | +.num { |
| 99 | + background-color: #ffe9ae; |
| 100 | + text-align:right; |
| 101 | + padding: 0 0.3em; |
| 102 | + width: 3em; |
| 103 | +} |
| 104 | + |
| 105 | +.warning { |
| 106 | + color: red |
| 107 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/create_attachment.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 108 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/show_bug.css |
— | — | @@ -0,0 +1,103 @@ |
| 2 | +.bz_alias_short_desc_container { |
| 3 | + margin: 8px 0; |
| 4 | + padding: 0.3em 0.3em 0.3em 0.5em; |
| 5 | + -moz-border-radius: 0.5em; |
| 6 | + font-size: 125%; |
| 7 | + font-weight: bold; |
| 8 | + background:transparent url(images/block-base.png) repeat-x scroll center bottom; |
| 9 | + border: 1px solid silver; |
| 10 | + repeat: repeat-x; |
| 11 | +} |
| 12 | + |
| 13 | +.bz_bug .edit_form { |
| 14 | + width: 100%; |
| 15 | +} |
| 16 | +.bz_bug .edit_form table { |
| 17 | + width: 100%; |
| 18 | +} |
| 19 | +.bz_bug .edit_form .text_input { |
| 20 | + width: 100%; |
| 21 | + min-width: 25em; |
| 22 | +} |
| 23 | +.bz_bug #alias { |
| 24 | + min-width: 0; |
| 25 | + width: 10em; |
| 26 | +} |
| 27 | + |
| 28 | +.flags_label { |
| 29 | + text-align: left; |
| 30 | +} |
| 31 | +table#flags { |
| 32 | + width: auto; |
| 33 | +} |
| 34 | + |
| 35 | +.bz_column_spacer { |
| 36 | + width: 2em; |
| 37 | +} |
| 38 | + |
| 39 | +.related_actions { |
| 40 | + font-size: 0.85em; |
| 41 | + float: right; |
| 42 | + list-style-type: none; |
| 43 | + white-space: nowrap; |
| 44 | + margin: 0; |
| 45 | + padding: 0; |
| 46 | +} |
| 47 | + |
| 48 | +.related_actions li { |
| 49 | + display: inline; |
| 50 | +} |
| 51 | + |
| 52 | +.bz_show_bug_column { |
| 53 | + vertical-align: top; |
| 54 | + border-width: 1px; |
| 55 | +} |
| 56 | + |
| 57 | +td.bz_section_spacer { |
| 58 | + height: 0; |
| 59 | + padding: 0 !important; |
| 60 | +} |
| 61 | + |
| 62 | +.bz_comment_head, .bz_first_comment_head { |
| 63 | + border: 1px solid silver; |
| 64 | +} |
| 65 | +.bz_comment_text { |
| 66 | + font-size: 115%; |
| 67 | +} |
| 68 | +#duplicate_settings, #votes_container { |
| 69 | + white-space: nowrap; |
| 70 | + |
| 71 | +} |
| 72 | + |
| 73 | +.bz_time_tracking_table { |
| 74 | + border-collapse: collapse; |
| 75 | +} |
| 76 | + |
| 77 | +.bz_time_tracking_table th { |
| 78 | + text-align: center; |
| 79 | +} |
| 80 | + |
| 81 | +.bz_time_tracking_table td { |
| 82 | + text-align: center; |
| 83 | +} |
| 84 | + |
| 85 | +.bz_time_tracking_table th, |
| 86 | +.bz_time_tracking_table td { |
| 87 | + padding: 4px; |
| 88 | +} |
| 89 | + |
| 90 | +.bz_time_tracking_table .bz_summarize_time { |
| 91 | + text-align: right; |
| 92 | +} |
| 93 | + |
| 94 | +#summary tr td { |
| 95 | + vertical-align:top; |
| 96 | +} |
| 97 | + |
| 98 | +#status { |
| 99 | + margin-bottom: 3ex; |
| 100 | +} |
| 101 | + |
| 102 | +.knob-buttons { |
| 103 | + float: right; |
| 104 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/show_bug.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 105 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/video-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/video-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
2 | 106 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/search-fade.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/search-fade.png |
___________________________________________________________________ |
Added: svn:mime-type |
3 | 107 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/news-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/news-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
4 | 108 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/document-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/document-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
5 | 109 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/bugzilla-logo.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/bugzilla-logo.png |
___________________________________________________________________ |
Added: svn:mime-type |
6 | 110 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/mail-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/mail-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
7 | 111 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/preferences-base.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/preferences-base.png |
___________________________________________________________________ |
Added: svn:mime-type |
8 | 112 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/page-fade.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/page-fade.png |
___________________________________________________________________ |
Added: svn:mime-type |
9 | 113 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/bugzilla-badge.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/bugzilla-badge.png |
___________________________________________________________________ |
Added: svn:mime-type |
10 | 114 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/border.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/border.png |
___________________________________________________________________ |
Added: svn:mime-type |
11 | 115 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/watch-icons.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/watch-icons.png |
___________________________________________________________________ |
Added: svn:mime-type |
12 | 116 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/tab-current-fade.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/tab-current-fade.png |
___________________________________________________________________ |
Added: svn:mime-type |
13 | 117 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/preferences-break.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/preferences-break.png |
___________________________________________________________________ |
Added: svn:mime-type |
14 | 118 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/portal-break.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/portal-break.png |
___________________________________________________________________ |
Added: svn:mime-type |
15 | 119 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/audio-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/audio-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
16 | 120 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/watch-icon-loading.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/watch-icon-loading.gif |
___________________________________________________________________ |
Added: svn:mime-type |
17 | 121 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/tab-normal-fade.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/tab-normal-fade.png |
___________________________________________________________________ |
Added: svn:mime-type |
18 | 122 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/preferences-fade.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/preferences-fade.png |
___________________________________________________________________ |
Added: svn:mime-type |
19 | 123 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/external-link-rtl-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/external-link-rtl-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
20 | 124 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/external-link-ltr-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/external-link-ltr-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
21 | 125 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/block-base.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/block-base.png |
___________________________________________________________________ |
Added: svn:mime-type |
22 | 126 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/preferences-edge.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/preferences-edge.png |
___________________________________________________________________ |
Added: svn:mime-type |
23 | 127 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/user-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/user-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
24 | 128 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/search-ltr.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/search-ltr.png |
___________________________________________________________________ |
Added: svn:mime-type |
25 | 129 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/search-rtl.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/search-rtl.png |
___________________________________________________________________ |
Added: svn:mime-type |
26 | 130 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/file-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/file-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
27 | 131 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/edit-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/edit-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
28 | 132 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/bullet-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/bullet-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
29 | 133 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/lock-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/lock-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
30 | 134 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/magnify-clip.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/magnify-clip.png |
___________________________________________________________________ |
Added: svn:mime-type |
31 | 135 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/talk-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/talk-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
32 | 136 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/portal-break-rtl.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/portal-break-rtl.png |
___________________________________________________________________ |
Added: svn:mime-type |
33 | 137 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/portal-break-ltr.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/portal-break-ltr.png |
___________________________________________________________________ |
Added: svn:mime-type |
34 | 138 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/link-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/link-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
35 | 139 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/page-base.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/page-base.png |
___________________________________________________________________ |
Added: svn:mime-type |
36 | 140 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/arrow-down-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/arrow-down-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
37 | 141 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/tab-break.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/images/tab-break.png |
___________________________________________________________________ |
Added: svn:mime-type |
38 | 142 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/bugzilla-ayb.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/bugzilla-ayb.png |
___________________________________________________________________ |
Added: svn:mime-type |
39 | 143 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/yui/calendar.css |
— | — | @@ -0,0 +1,7 @@ |
| 2 | +/* |
| 3 | +Copyright (c) 2008, Yahoo! Inc. All rights reserved. |
| 4 | +Code licensed under the BSD License: |
| 5 | +http://developer.yahoo.net/yui/license.txt |
| 6 | +version: 2.6.0 |
| 7 | +*/ |
| 8 | +.yui-calcontainer{position:relative;float:left;_overflow:hidden;}.yui-calcontainer iframe{position:absolute;border:none;margin:0;padding:0;z-index:0;width:100%;height:100%;left:0px;top:0px;}.yui-calcontainer iframe.fixedsize{width:50em;height:50em;top:-1px;left:-1px;}.yui-calcontainer.multi .groupcal{z-index:1;float:left;position:relative;}.yui-calcontainer .title{position:relative;z-index:1;}.yui-calcontainer .close-icon{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden;}.yui-calendar{position:relative;}.yui-calendar .calnavleft{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden;}.yui-calendar .calnavright{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden;}.yui-calendar .calheader{position:relative;width:100%;text-align:center;}.yui-calcontainer .yui-cal-nav-mask{position:absolute;z-index:2;margin:0;padding:0;width:100%;height:100%;_width:0;_height:0;left:0;top:0;display:none;}.yui-calcontainer .yui-cal-nav{position:absolute;z-index:3;top:0;display:none;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{display:-moz-inline-box;display:inline-block;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{display:block;*display:inline-block;*overflow:visible;border:none;background-color:transparent;cursor:pointer;}.yui-calendar .calbody a:hover{background:inherit;}p#clear{clear:left;padding-top:10px;}.yui-skin-sam .yui-calcontainer{background-color:#f2f2f2;border:1px solid #808080;padding:10px;}.yui-skin-sam .yui-calcontainer.multi{padding:0 5px 0 5px;}.yui-skin-sam .yui-calcontainer.multi .groupcal{background-color:transparent;border:none;padding:10px 5px 10px 5px;margin:0;}.yui-skin-sam .yui-calcontainer .title{background:url(sprite.png) repeat-x 0 0;border-bottom:1px solid #cccccc;font:100% sans-serif;color:#000;font-weight:bold;height:auto;padding:.4em;margin:0 -10px 10px -10px;top:0;left:0;text-align:left;}.yui-skin-sam .yui-calcontainer.multi .title{margin:0 -5px 0 -5px;}.yui-skin-sam .yui-calcontainer.withtitle{padding-top:0;}.yui-skin-sam .yui-calcontainer .calclose{background:url(sprite.png) no-repeat 0 -300px;width:25px;height:15px;top:.4em;right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar{border-spacing:0;border-collapse:collapse;font:100% sans-serif;text-align:center;margin:0;}.yui-skin-sam .yui-calendar .calhead{background:transparent;border:none;vertical-align:middle;padding:0;}.yui-skin-sam .yui-calendar .calheader{background:transparent;font-weight:bold;padding:0 0 .6em 0;text-align:center;}.yui-skin-sam .yui-calendar .calheader img{border:none;}.yui-skin-sam .yui-calendar .calnavleft{background:url(sprite.png) no-repeat 0 -450px;width:25px;height:15px;top:0;bottom:0;left:-10px;margin-left:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calnavright{background:url(sprite.png) no-repeat 0 -500px;width:25px;height:15px;top:0;bottom:0;right:-10px;margin-right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calweekdayrow{height:2em;}.yui-skin-sam .yui-calendar .calweekdayrow th{padding:0;border:none;}.yui-skin-sam .yui-calendar .calweekdaycell{color:#000;font-weight:bold;text-align:center;width:2em;}.yui-skin-sam .yui-calendar .calfoot{background-color:#f2f2f2;}.yui-skin-sam .yui-calendar .calrowhead,.yui-skin-sam .yui-calendar .calrowfoot{color:#a6a6a6;font-size:85%;font-style:normal;font-weight:normal;border:none;}.yui-skin-sam .yui-calendar .calrowhead{text-align:right;padding:0 2px 0 0;}.yui-skin-sam .yui-calendar .calrowfoot{text-align:left;padding:0 0 0 2px;}.yui-skin-sam .yui-calendar td.calcell{border:1px solid #cccccc;background:#fff;padding:1px;height:1.6em;line-height:1.6em;text-align:center;white-space:nowrap;}.yui-skin-sam .yui-calendar td.calcell a{color:#0066cc;display:block;height:100%;text-decoration:none;}.yui-skin-sam .yui-calendar td.calcell.today{background-color:#000;}.yui-skin-sam .yui-calendar td.calcell.today a{background-color:#fff;}.yui-skin-sam .yui-calendar td.calcell.oom{background-color:#cccccc;color:#a6a6a6;cursor:default;}.yui-skin-sam .yui-calendar td.calcell.selected{background-color:#fff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.selected a{background-color:#b3d4ff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.calcellhover{background-color:#426fd9;color:#fff;cursor:pointer;}.yui-skin-sam .yui-calendar td.calcell.calcellhover a{background-color:#426fd9;color:#fff;}.yui-skin-sam .yui-calendar td.calcell.previous{color:#e0e0e0;}.yui-skin-sam .yui-calendar td.calcell.restricted{text-decoration:line-through;}.yui-skin-sam .yui-calendar td.calcell.highlight1{background-color:#ccff99;}.yui-skin-sam .yui-calendar td.calcell.highlight2{background-color:#99ccff;}.yui-skin-sam .yui-calendar td.calcell.highlight3{background-color:#ffcccc;}.yui-skin-sam .yui-calendar td.calcell.highlight4{background-color:#ccff99;}.yui-skin-sam .yui-calendar a.calnav{border:1px solid #f2f2f2;padding:0 4px;text-decoration:none;color:#000;zoom:1;}.yui-skin-sam .yui-calendar a.calnav:hover{background:url(sprite.png) repeat-x 0 0;border-color:#A0A0A0;cursor:pointer;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mask{background-color:#000;opacity:0.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-calcontainer .yui-cal-nav{font-family:arial,helvetica,clean,sans-serif;font-size:93%;border:1px solid #808080;left:50%;margin-left:-7em;width:14em;padding:0;top:2.5em;background-color:#f2f2f2;}.yui-skin-sam .yui-calcontainer.withtitle .yui-cal-nav{top:4.5em;}.yui-skin-sam .yui-calcontainer.multi .yui-cal-nav{width:16em;margin-left:-8em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y,.yui-skin-sam .yui-calcontainer .yui-cal-nav-m,.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{padding:5px 10px 5px 10px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{text-align:center;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-e{margin-top:5px;padding:5px;background-color:#EDF5FF;border-top:1px solid black;display:none;}.yui-skin-sam .yui-calcontainer .yui-cal-nav label{display:block;font-weight:bold;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mc{width:100%;_width:auto;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y input.yui-invalid{background-color:#FFEE69;border:1px solid #000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-yc{width:4em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{border:1px solid #808080;background:url(sprite.png) repeat-x 0 0;background-color:#ccc;margin:auto .15em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{padding:0 8px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default{border:1px solid #304369;background-color:#426fd9;background:url(sprite.png) repeat-x 0 -1400px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default button{color:#fff;} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/yui/calendar.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 9 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/yui/sprite.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/yui/sprite.png |
___________________________________________________________________ |
Added: svn:mime-type |
2 | 10 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/index/account.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/index/account.gif |
___________________________________________________________________ |
Added: svn:mime-type |
3 | 11 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/index/bug.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/index/bug.gif |
___________________________________________________________________ |
Added: svn:mime-type |
4 | 12 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/index/search.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/index/search.gif |
___________________________________________________________________ |
Added: svn:mime-type |
5 | 13 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/params.css |
— | — | @@ -0,0 +1,61 @@ |
| 2 | +#menu { |
| 3 | + width: 10em; |
| 4 | + margin-top: 1em; |
| 5 | + margin-right: 0.5em; |
| 6 | + border: solid thin; |
| 7 | + border-spacing: 0px; |
| 8 | + border-collapse: collapse; |
| 9 | + text-align: center; |
| 10 | + color: black; |
| 11 | + background-color: #edf2f2; |
| 12 | + font-weight: normal; |
| 13 | +} |
| 14 | + |
| 15 | +#menu a:link, #menu a:visited { |
| 16 | + color: #039; |
| 17 | + background-color: transparent; |
| 18 | +} |
| 19 | + |
| 20 | +#menu a:hover, #menu a:active { |
| 21 | + color: red; |
| 22 | + background-color: transparent; |
| 23 | +} |
| 24 | + |
| 25 | +#menu td { |
| 26 | + border: solid thin; |
| 27 | + padding: 0.2em 0.5em; |
| 28 | +} |
| 29 | + |
| 30 | +table td { |
| 31 | + vertical-align: top; |
| 32 | +} |
| 33 | + |
| 34 | +td.selected_section { |
| 35 | + color: #090; |
| 36 | + background-color: white; |
| 37 | +} |
| 38 | + |
| 39 | +td.index { |
| 40 | + color: black; |
| 41 | + background-color: #edf; |
| 42 | +} |
| 43 | + |
| 44 | +dt { |
| 45 | + font-weight: bold; |
| 46 | +} |
| 47 | + |
| 48 | +dd { |
| 49 | + margin-bottom: 1.5em; |
| 50 | +} |
| 51 | + |
| 52 | +.sortlist_separator { |
| 53 | + font-weight: bold; |
| 54 | + font-size: 80%; |
| 55 | + background-color: #dddddd; |
| 56 | +} |
| 57 | + |
| 58 | +.contribute { |
| 59 | + border: 1px dotted black; |
| 60 | + padding: .5em; |
| 61 | + font-size: small; |
| 62 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/params.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 63 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/dependency-tree/tree-open.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/dependency-tree/tree-open.png |
___________________________________________________________________ |
Added: svn:mime-type |
2 | 64 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/dependency-tree/tree.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/dependency-tree/tree.png |
___________________________________________________________________ |
Added: svn:mime-type |
3 | 65 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/dependency-tree/tree-closed.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/dependency-tree/tree-closed.png |
___________________________________________________________________ |
Added: svn:mime-type |
4 | 66 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/dependency-tree/bug-item.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/skins/custom/dependency-tree/bug-item.png |
___________________________________________________________________ |
Added: svn:mime-type |
5 | 67 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/Bugzilla/Template.pm |
— | — | @@ -0,0 +1,948 @@ |
| 2 | +# -*- Mode: perl; indent-tabs-mode: nil -*- |
| 3 | +# |
| 4 | +# The contents of this file are subject to the Mozilla Public |
| 5 | +# License Version 1.1 (the "License"); you may not use this file |
| 6 | +# except in compliance with the License. You may obtain a copy of |
| 7 | +# the License at http://www.mozilla.org/MPL/ |
| 8 | +# |
| 9 | +# Software distributed under the License is distributed on an "AS |
| 10 | +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 | +# implied. See the License for the specific language governing |
| 12 | +# rights and limitations under the License. |
| 13 | +# |
| 14 | +# The Original Code is the Bugzilla Bug Tracking System. |
| 15 | +# |
| 16 | +# The Initial Developer of the Original Code is Netscape Communications |
| 17 | +# Corporation. Portions created by Netscape are |
| 18 | +# Copyright (C) 1998 Netscape Communications Corporation. All |
| 19 | +# Rights Reserved. |
| 20 | +# |
| 21 | +# Contributor(s): Terry Weissman <terry@mozilla.org> |
| 22 | +# Dan Mosedale <dmose@mozilla.org> |
| 23 | +# Jacob Steenhagen <jake@bugzilla.org> |
| 24 | +# Bradley Baetz <bbaetz@student.usyd.edu.au> |
| 25 | +# Christopher Aillon <christopher@aillon.com> |
| 26 | +# Tobias Burnus <burnus@net-b.de> |
| 27 | +# Myk Melez <myk@mozilla.org> |
| 28 | +# Max Kanat-Alexander <mkanat@bugzilla.org> |
| 29 | +# Frédéric Buclin <LpSolit@gmail.com> |
| 30 | +# Greg Hendricks <ghendricks@novell.com> |
| 31 | +# David D. Kilzer <ddkilzer@kilzer.net> |
| 32 | + |
| 33 | + |
| 34 | +package Bugzilla::Template; |
| 35 | + |
| 36 | +use strict; |
| 37 | + |
| 38 | +use Bugzilla::Constants; |
| 39 | +use Bugzilla::Install::Requirements; |
| 40 | +use Bugzilla::Install::Util qw(install_string template_include_path include_languages); |
| 41 | +use Bugzilla::Util; |
| 42 | +use Bugzilla::User; |
| 43 | +use Bugzilla::Error; |
| 44 | +use Bugzilla::Status; |
| 45 | +use Bugzilla::Token; |
| 46 | + |
| 47 | +use Cwd qw(abs_path); |
| 48 | +use MIME::Base64; |
| 49 | +use Date::Format (); |
| 50 | +use File::Basename qw(dirname); |
| 51 | +use File::Find; |
| 52 | +use File::Path qw(rmtree mkpath); |
| 53 | +use File::Spec; |
| 54 | +use IO::Dir; |
| 55 | + |
| 56 | +use base qw(Template); |
| 57 | + |
| 58 | +# Convert the constants in the Bugzilla::Constants module into a hash we can |
| 59 | +# pass to the template object for reflection into its "constants" namespace |
| 60 | +# (which is like its "variables" namespace, but for constants). To do so, we |
| 61 | +# traverse the arrays of exported and exportable symbols and ignoring the rest |
| 62 | +# (which, if Constants.pm exports only constants, as it should, will be nothing else). |
| 63 | +sub _load_constants { |
| 64 | + my %constants; |
| 65 | + foreach my $constant (@Bugzilla::Constants::EXPORT, |
| 66 | + @Bugzilla::Constants::EXPORT_OK) |
| 67 | + { |
| 68 | + if (ref Bugzilla::Constants->$constant) { |
| 69 | + $constants{$constant} = Bugzilla::Constants->$constant; |
| 70 | + } |
| 71 | + else { |
| 72 | + my @list = (Bugzilla::Constants->$constant); |
| 73 | + $constants{$constant} = (scalar(@list) == 1) ? $list[0] : \@list; |
| 74 | + } |
| 75 | + } |
| 76 | + return \%constants; |
| 77 | +} |
| 78 | + |
| 79 | +# Returns the path to the templates based on the Accept-Language |
| 80 | +# settings of the user and of the available languages |
| 81 | +# If no Accept-Language is present it uses the defined default |
| 82 | +# Templates may also be found in the extensions/ tree |
| 83 | +sub getTemplateIncludePath { |
| 84 | + my $cache = Bugzilla->request_cache; |
| 85 | + my $lang = $cache->{'language'} || ''; |
| 86 | + $cache->{"template_include_path_$lang"} ||= template_include_path({ |
| 87 | + use_languages => Bugzilla->languages, |
| 88 | + only_language => $lang }); |
| 89 | + return $cache->{"template_include_path_$lang"}; |
| 90 | +} |
| 91 | + |
| 92 | +sub get_format { |
| 93 | + my $self = shift; |
| 94 | + my ($template, $format, $ctype) = @_; |
| 95 | + |
| 96 | + $ctype ||= 'html'; |
| 97 | + $format ||= ''; |
| 98 | + |
| 99 | + # Security - allow letters and a hyphen only |
| 100 | + $ctype =~ s/[^a-zA-Z\-]//g; |
| 101 | + $format =~ s/[^a-zA-Z\-]//g; |
| 102 | + trick_taint($ctype); |
| 103 | + trick_taint($format); |
| 104 | + |
| 105 | + $template .= ($format ? "-$format" : ""); |
| 106 | + $template .= ".$ctype.tmpl"; |
| 107 | + |
| 108 | + # Now check that the template actually exists. We only want to check |
| 109 | + # if the template exists; any other errors (eg parse errors) will |
| 110 | + # end up being detected later. |
| 111 | + eval { |
| 112 | + $self->context->template($template); |
| 113 | + }; |
| 114 | + # This parsing may seem fragile, but it's OK: |
| 115 | + # http://lists.template-toolkit.org/pipermail/templates/2003-March/004370.html |
| 116 | + # Even if it is wrong, any sort of error is going to cause a failure |
| 117 | + # eventually, so the only issue would be an incorrect error message |
| 118 | + if ($@ && $@->info =~ /: not found$/) { |
| 119 | + ThrowUserError('format_not_found', {'format' => $format, |
| 120 | + 'ctype' => $ctype}); |
| 121 | + } |
| 122 | + |
| 123 | + # Else, just return the info |
| 124 | + return |
| 125 | + { |
| 126 | + 'template' => $template, |
| 127 | + 'extension' => $ctype, |
| 128 | + 'ctype' => Bugzilla::Constants::contenttypes->{$ctype} |
| 129 | + }; |
| 130 | +} |
| 131 | + |
| 132 | +# This routine quoteUrls contains inspirations from the HTML::FromText CPAN |
| 133 | +# module by Gareth Rees <garethr@cre.canon.co.uk>. It has been heavily hacked, |
| 134 | +# all that is really recognizable from the original is bits of the regular |
| 135 | +# expressions. |
| 136 | +# This has been rewritten to be faster, mainly by substituting 'as we go'. |
| 137 | +# If you want to modify this routine, read the comments carefully |
| 138 | + |
| 139 | +sub quoteUrls { |
| 140 | + my ($text, $curr_bugid, $already_wrapped) = (@_); |
| 141 | + return $text unless $text; |
| 142 | + |
| 143 | + # We use /g for speed, but uris can have other things inside them |
| 144 | + # (http://foo/bug#3 for example). Filtering that out filters valid |
| 145 | + # bug refs out, so we have to do replacements. |
| 146 | + # mailto can't contain space or #, so we don't have to bother for that |
| 147 | + # Do this by escaping \0 to \1\0, and replacing matches with \0\0$count\0\0 |
| 148 | + # \0 is used because it's unlikely to occur in the text, so the cost of |
| 149 | + # doing this should be very small |
| 150 | + |
| 151 | + # escape the 2nd escape char we're using |
| 152 | + my $chr1 = chr(1); |
| 153 | + $text =~ s/\0/$chr1\0/g; |
| 154 | + |
| 155 | + # If the comment is already wrapped, we should ignore newlines when |
| 156 | + # looking for matching regexps. Else we should take them into account. |
| 157 | + my $s = $already_wrapped ? qr/\s/ : qr/[[:blank:]]/; |
| 158 | + |
| 159 | + # However, note that adding the title (for buglinks) can affect things |
| 160 | + # In particular, attachment matches go before bug titles, so that titles |
| 161 | + # with 'attachment 1' don't double match. |
| 162 | + # Dupe checks go afterwards, because that uses ^ and \Z, which won't occur |
| 163 | + # if it was substituted as a bug title (since that always involve leading |
| 164 | + # and trailing text) |
| 165 | + |
| 166 | + # Because of entities, it's easier (and quicker) to do this before escaping |
| 167 | + |
| 168 | + my @things; |
| 169 | + my $count = 0; |
| 170 | + my $tmp; |
| 171 | + |
| 172 | + # Provide tooltips for full bug links (Bug 74355) |
| 173 | + my $urlbase_re = '(' . join('|', |
| 174 | + map { qr/$_/ } grep($_, Bugzilla->params->{'urlbase'}, |
| 175 | + Bugzilla->params->{'sslbase'})) . ')'; |
| 176 | + $text =~ s~\b(${urlbase_re}\Qshow_bug.cgi?id=\E([0-9]+)(\#c([0-9]+))?)\b |
| 177 | + ~($things[$count++] = get_bug_link($3, $1, { comment_num => $5 })) && |
| 178 | + ("\0\0" . ($count-1) . "\0\0") |
| 179 | + ~egox; |
| 180 | + |
| 181 | + # non-mailto protocols |
| 182 | + my $safe_protocols = join('|', SAFE_PROTOCOLS); |
| 183 | + my $protocol_re = qr/($safe_protocols)/i; |
| 184 | + |
| 185 | + $text =~ s~\b(${protocol_re}: # The protocol: |
| 186 | + [^\s<>\"]+ # Any non-whitespace |
| 187 | + [\w\/]) # so that we end in \w or / |
| 188 | + ~($tmp = html_quote($1)) && |
| 189 | + ($things[$count++] = "<a href=\"$tmp\">$tmp</a>") && |
| 190 | + ("\0\0" . ($count-1) . "\0\0") |
| 191 | + ~egox; |
| 192 | + |
| 193 | + # **** Dirty hack! --brion |
| 194 | + $text =~ s~\[\[([a-zA-Z0-9_ ,./'()!#%:\x80-\xff-]+)\]\] |
| 195 | + ~($tmp = html_quote($1)) && |
| 196 | + ($things[$count++] = "<a href=\"http://en.wikipedia.org/wiki/$tmp\">[[$tmp]]</a>") && |
| 197 | + ("\0\0" . ($count-1) . "\0\0") |
| 198 | + ~egox; |
| 199 | + # **** end dirty hack |
| 200 | + # **** More dirty hacks! --brion |
| 201 | + $text =~ s~\br(\d+)\b |
| 202 | + ~($things[$count++] = "<a href=\"http://www.mediawiki.org" . |
| 203 | + "/wiki/Special:Code/MediaWiki/$1\" " . |
| 204 | + "title=\"revision $1 in SVN\">r$1</a>") && |
| 205 | + ("\0\0" . ($count-1) . "\0\0") |
| 206 | + ~egox; |
| 207 | + # **** end dirty hack |
| 208 | + |
| 209 | + # We have to quote now, otherwise the html itself is escaped |
| 210 | + # THIS MEANS THAT A LITERAL ", <, >, ' MUST BE ESCAPED FOR A MATCH |
| 211 | + |
| 212 | + $text = html_quote($text); |
| 213 | + |
| 214 | + # Color quoted text |
| 215 | + $text =~ s~^(>.+)$~<span class="quote">$1</span >~mg; |
| 216 | + $text =~ s~</span >\n<span class="quote">~\n~g; |
| 217 | + |
| 218 | + # mailto: |
| 219 | + # Use |<nothing> so that $1 is defined regardless |
| 220 | + $text =~ s~\b(mailto:|)?([\w\.\-\+\=]+\@[\w\-]+(?:\.[\w\-]+)+)\b |
| 221 | + ~<a href=\"mailto:$2\">$1$2</a>~igx; |
| 222 | + |
| 223 | + # attachment links - handle both cases separately for simplicity |
| 224 | + $text =~ s~((?:^Created\ an\ |\b)attachment\s*\(id=(\d+)\)(\s\[edit\])?) |
| 225 | + ~($things[$count++] = get_attachment_link($2, $1)) && |
| 226 | + ("\0\0" . ($count-1) . "\0\0") |
| 227 | + ~egmx; |
| 228 | + |
| 229 | + $text =~ s~\b(attachment$s*\#?$s*(\d+)) |
| 230 | + ~($things[$count++] = get_attachment_link($2, $1)) && |
| 231 | + ("\0\0" . ($count-1) . "\0\0") |
| 232 | + ~egmxi; |
| 233 | + |
| 234 | + # Current bug ID this comment belongs to |
| 235 | + my $current_bugurl = $curr_bugid ? "show_bug.cgi?id=$curr_bugid" : ""; |
| 236 | + |
| 237 | + # This handles bug a, comment b type stuff. Because we're using /g |
| 238 | + # we have to do this in one pattern, and so this is semi-messy. |
| 239 | + # Also, we can't use $bug_re?$comment_re? because that will match the |
| 240 | + # empty string |
| 241 | + my $bug_word = get_text('term', { term => 'bug' }); |
| 242 | + my $bug_re = qr/\Q$bug_word\E$s*\#?$s*(\d+)/i; |
| 243 | + my $comment_re = qr/comment$s*\#?$s*(\d+)/i; |
| 244 | + $text =~ s~\b($bug_re(?:$s*,?$s*$comment_re)?|$comment_re) |
| 245 | + ~ # We have several choices. $1 here is the link, and $2-4 are set |
| 246 | + # depending on which part matched |
| 247 | + (defined($2) ? get_bug_link($2, $1, { comment_num => $3 }) : |
| 248 | + "<a href=\"$current_bugurl#c$4\">$1</a>") |
| 249 | + ~egox; |
| 250 | + |
| 251 | + # Old duplicate markers. These don't use $bug_word because they are old |
| 252 | + # and were never customizable. |
| 253 | + $text =~ s~(?<=^\*\*\*\ This\ bug\ has\ been\ marked\ as\ a\ duplicate\ of\ ) |
| 254 | + (\d+) |
| 255 | + (?=\ \*\*\*\Z) |
| 256 | + ~get_bug_link($1, $1) |
| 257 | + ~egmx; |
| 258 | + |
| 259 | + # Now remove the encoding hacks |
| 260 | + $text =~ s/\0\0(\d+)\0\0/$things[$1]/eg; |
| 261 | + $text =~ s/$chr1\0/\0/g; |
| 262 | + |
| 263 | + return $text; |
| 264 | +} |
| 265 | + |
| 266 | +# Creates a link to an attachment, including its title. |
| 267 | +sub get_attachment_link { |
| 268 | + my ($attachid, $link_text) = @_; |
| 269 | + my $dbh = Bugzilla->dbh; |
| 270 | + |
| 271 | + detaint_natural($attachid) |
| 272 | + || die "get_attachment_link() called with non-integer attachment number"; |
| 273 | + |
| 274 | + my ($bugid, $isobsolete, $desc) = |
| 275 | + $dbh->selectrow_array('SELECT bug_id, isobsolete, description |
| 276 | + FROM attachments WHERE attach_id = ?', |
| 277 | + undef, $attachid); |
| 278 | + |
| 279 | + if ($bugid) { |
| 280 | + my $title = ""; |
| 281 | + my $className = ""; |
| 282 | + if (Bugzilla->user->can_see_bug($bugid)) { |
| 283 | + $title = $desc; |
| 284 | + } |
| 285 | + if ($isobsolete) { |
| 286 | + $className = "bz_obsolete"; |
| 287 | + } |
| 288 | + # Prevent code injection in the title. |
| 289 | + $title = html_quote(clean_text($title)); |
| 290 | + |
| 291 | + $link_text =~ s/ \[details\]$//; |
| 292 | + my $linkval = "attachment.cgi?id=$attachid"; |
| 293 | + # Whitespace matters here because these links are in <pre> tags. |
| 294 | + return qq|<span class="$className">| |
| 295 | + . qq|<a href="${linkval}" name="attach_${attachid}" title="$title">$link_text</a>| |
| 296 | + . qq| <a href="${linkval}&action=edit" title="$title">[details]</a>| |
| 297 | + . qq|</span>|; |
| 298 | + } |
| 299 | + else { |
| 300 | + return qq{$link_text}; |
| 301 | + } |
| 302 | +} |
| 303 | + |
| 304 | +# Creates a link to a bug, including its title. |
| 305 | +# It takes either two or three parameters: |
| 306 | +# - The bug number |
| 307 | +# - The link text, to place between the <a>..</a> |
| 308 | +# - An optional comment number, for linking to a particular |
| 309 | +# comment in the bug |
| 310 | + |
| 311 | +sub get_bug_link { |
| 312 | + my ($bug_num, $link_text, $options) = @_; |
| 313 | + my $dbh = Bugzilla->dbh; |
| 314 | + |
| 315 | + if (!defined($bug_num) || ($bug_num eq "")) { |
| 316 | + return "<missing bug number>"; |
| 317 | + } |
| 318 | + my $quote_bug_num = html_quote($bug_num); |
| 319 | + detaint_natural($bug_num) || return "<invalid bug number: $quote_bug_num>"; |
| 320 | + |
| 321 | + my ($bug_alias, $bug_state, $bug_res, $bug_desc) = |
| 322 | + $dbh->selectrow_array('SELECT bugs.alias, bugs.bug_status, bugs.resolution, bugs.short_desc |
| 323 | + FROM bugs WHERE bugs.bug_id = ?', |
| 324 | + undef, $bug_num); |
| 325 | + |
| 326 | + if ($bug_state) { |
| 327 | + # Initialize these variables to be "" so that we don't get warnings |
| 328 | + # if we don't change them below (which is highly likely). |
| 329 | + my ($pre, $title, $post) = ("", "", ""); |
| 330 | + |
| 331 | + $title = get_text('get_status', {status => $bug_state}); |
| 332 | + if ($bug_state eq 'UNCONFIRMED') { |
| 333 | + $pre = "<i>"; |
| 334 | + $post = "</i>"; |
| 335 | + } |
| 336 | + elsif (!is_open_state($bug_state)) { |
| 337 | + $pre = '<span class="bz_closed">'; |
| 338 | + $title .= ' ' . get_text('get_resolution', {resolution => $bug_res}); |
| 339 | + $post = '</span>'; |
| 340 | + } |
| 341 | + if (Bugzilla->user->can_see_bug($bug_num)) { |
| 342 | + $title .= " - $bug_desc"; |
| 343 | + if ($options->{use_alias} && $link_text =~ /^\d+$/ && $bug_alias) { |
| 344 | + $link_text = $bug_alias; |
| 345 | + } |
| 346 | + } |
| 347 | + # Prevent code injection in the title. |
| 348 | + $title = html_quote(clean_text($title)); |
| 349 | + |
| 350 | + my $linkval = "show_bug.cgi?id=$bug_num"; |
| 351 | + if ($options->{comment_num}) { |
| 352 | + $linkval .= "#c" . $options->{comment_num}; |
| 353 | + } |
| 354 | + return qq{$pre<a href="$linkval" title="$title">$link_text</a>$post}; |
| 355 | + } |
| 356 | + else { |
| 357 | + return qq{$link_text}; |
| 358 | + } |
| 359 | +} |
| 360 | + |
| 361 | +############################################################################### |
| 362 | +# Templatization Code |
| 363 | + |
| 364 | +# The Template Toolkit throws an error if a loop iterates >1000 times. |
| 365 | +# We want to raise that limit. |
| 366 | +# NOTE: If you change this number, you MUST RE-RUN checksetup.pl!!! |
| 367 | +# If you do not re-run checksetup.pl, the change you make will not apply |
| 368 | +$Template::Directive::WHILE_MAX = 1000000; |
| 369 | + |
| 370 | +# Use the Toolkit Template's Stash module to add utility pseudo-methods |
| 371 | +# to template variables. |
| 372 | +use Template::Stash; |
| 373 | + |
| 374 | +# Add "contains***" methods to list variables that search for one or more |
| 375 | +# items in a list and return boolean values representing whether or not |
| 376 | +# one/all/any item(s) were found. |
| 377 | +$Template::Stash::LIST_OPS->{ contains } = |
| 378 | + sub { |
| 379 | + my ($list, $item) = @_; |
| 380 | + return grep($_ eq $item, @$list); |
| 381 | + }; |
| 382 | + |
| 383 | +$Template::Stash::LIST_OPS->{ containsany } = |
| 384 | + sub { |
| 385 | + my ($list, $items) = @_; |
| 386 | + foreach my $item (@$items) { |
| 387 | + return 1 if grep($_ eq $item, @$list); |
| 388 | + } |
| 389 | + return 0; |
| 390 | + }; |
| 391 | + |
| 392 | +# Clone the array reference to leave the original one unaltered. |
| 393 | +$Template::Stash::LIST_OPS->{ clone } = |
| 394 | + sub { |
| 395 | + my $list = shift; |
| 396 | + return [@$list]; |
| 397 | + }; |
| 398 | + |
| 399 | +# Allow us to still get the scalar if we use the list operation ".0" on it, |
| 400 | +# as we often do for defaults in query.cgi and other places. |
| 401 | +$Template::Stash::SCALAR_OPS->{ 0 } = |
| 402 | + sub { |
| 403 | + return $_[0]; |
| 404 | + }; |
| 405 | + |
| 406 | +# Add a "substr" method to the Template Toolkit's "scalar" object |
| 407 | +# that returns a substring of a string. |
| 408 | +$Template::Stash::SCALAR_OPS->{ substr } = |
| 409 | + sub { |
| 410 | + my ($scalar, $offset, $length) = @_; |
| 411 | + return substr($scalar, $offset, $length); |
| 412 | + }; |
| 413 | + |
| 414 | +# Add a "truncate" method to the Template Toolkit's "scalar" object |
| 415 | +# that truncates a string to a certain length. |
| 416 | +$Template::Stash::SCALAR_OPS->{ truncate } = |
| 417 | + sub { |
| 418 | + my ($string, $length, $ellipsis) = @_; |
| 419 | + $ellipsis ||= ""; |
| 420 | + |
| 421 | + return $string if !$length || length($string) <= $length; |
| 422 | + |
| 423 | + my $strlen = $length - length($ellipsis); |
| 424 | + my $newstr = substr($string, 0, $strlen) . $ellipsis; |
| 425 | + return $newstr; |
| 426 | + }; |
| 427 | + |
| 428 | +# Create the template object that processes templates and specify |
| 429 | +# configuration parameters that apply to all templates. |
| 430 | + |
| 431 | +############################################################################### |
| 432 | + |
| 433 | +# Construct the Template object |
| 434 | + |
| 435 | +# Note that all of the failure cases here can't use templateable errors, |
| 436 | +# since we won't have a template to use... |
| 437 | + |
| 438 | +sub create { |
| 439 | + my $class = shift; |
| 440 | + my %opts = @_; |
| 441 | + |
| 442 | + # checksetup.pl will call us once for any template/lang directory. |
| 443 | + # We need a possibility to reset the cache, so that no files from |
| 444 | + # the previous language pollute the action. |
| 445 | + if ($opts{'clean_cache'}) { |
| 446 | + delete Bugzilla->request_cache->{template_include_path_}; |
| 447 | + } |
| 448 | + |
| 449 | + # IMPORTANT - If you make any configuration changes here, make sure to |
| 450 | + # make them in t/004.template.t and checksetup.pl. |
| 451 | + |
| 452 | + return $class->new({ |
| 453 | + # Colon-separated list of directories containing templates. |
| 454 | + INCLUDE_PATH => [\&getTemplateIncludePath], |
| 455 | + |
| 456 | + # Remove white-space before template directives (PRE_CHOMP) and at the |
| 457 | + # beginning and end of templates and template blocks (TRIM) for better |
| 458 | + # looking, more compact content. Use the plus sign at the beginning |
| 459 | + # of directives to maintain white space (i.e. [%+ DIRECTIVE %]). |
| 460 | + PRE_CHOMP => 1, |
| 461 | + TRIM => 1, |
| 462 | + |
| 463 | + COMPILE_DIR => bz_locations()->{'datadir'} . "/template", |
| 464 | + |
| 465 | + # Initialize templates (f.e. by loading plugins like Hook). |
| 466 | + PRE_PROCESS => "global/initialize.none.tmpl", |
| 467 | + |
| 468 | + ENCODING => Bugzilla->params->{'utf8'} ? 'UTF-8' : undef, |
| 469 | + |
| 470 | + # Functions for processing text within templates in various ways. |
| 471 | + # IMPORTANT! When adding a filter here that does not override a |
| 472 | + # built-in filter, please also add a stub filter to t/004template.t. |
| 473 | + FILTERS => { |
| 474 | + |
| 475 | + # Render text in required style. |
| 476 | + |
| 477 | + inactive => [ |
| 478 | + sub { |
| 479 | + my($context, $isinactive) = @_; |
| 480 | + return sub { |
| 481 | + return $isinactive ? '<span class="bz_inactive">'.$_[0].'</span>' : $_[0]; |
| 482 | + } |
| 483 | + }, 1 |
| 484 | + ], |
| 485 | + |
| 486 | + closed => [ |
| 487 | + sub { |
| 488 | + my($context, $isclosed) = @_; |
| 489 | + return sub { |
| 490 | + return $isclosed ? '<span class="bz_closed">'.$_[0].'</span>' : $_[0]; |
| 491 | + } |
| 492 | + }, 1 |
| 493 | + ], |
| 494 | + |
| 495 | + obsolete => [ |
| 496 | + sub { |
| 497 | + my($context, $isobsolete) = @_; |
| 498 | + return sub { |
| 499 | + return $isobsolete ? '<span class="bz_obsolete">'.$_[0].'</span>' : $_[0]; |
| 500 | + } |
| 501 | + }, 1 |
| 502 | + ], |
| 503 | + |
| 504 | + # Returns the text with backslashes, single/double quotes, |
| 505 | + # and newlines/carriage returns escaped for use in JS strings. |
| 506 | + js => sub { |
| 507 | + my ($var) = @_; |
| 508 | + $var =~ s/([\\\'\"\/])/\\$1/g; |
| 509 | + $var =~ s/\n/\\n/g; |
| 510 | + $var =~ s/\r/\\r/g; |
| 511 | + $var =~ s/\@/\\x40/g; # anti-spam for email addresses |
| 512 | + $var =~ s/</\\x3c/g; |
| 513 | + return $var; |
| 514 | + }, |
| 515 | + |
| 516 | + # Converts data to base64 |
| 517 | + base64 => sub { |
| 518 | + my ($data) = @_; |
| 519 | + return encode_base64($data); |
| 520 | + }, |
| 521 | + |
| 522 | + # HTML collapses newlines in element attributes to a single space, |
| 523 | + # so form elements which may have whitespace (ie comments) need |
| 524 | + # to be encoded using 
 |
| 525 | + # See bugs 4928, 22983 and 32000 for more details |
| 526 | + html_linebreak => sub { |
| 527 | + my ($var) = @_; |
| 528 | + $var =~ s/\r\n/\
/g; |
| 529 | + $var =~ s/\n\r/\
/g; |
| 530 | + $var =~ s/\r/\
/g; |
| 531 | + $var =~ s/\n/\
/g; |
| 532 | + return $var; |
| 533 | + }, |
| 534 | + |
| 535 | + # Prevents line break on hyphens and whitespaces. |
| 536 | + no_break => sub { |
| 537 | + my ($var) = @_; |
| 538 | + $var =~ s/ /\ /g; |
| 539 | + $var =~ s/-/\‑/g; |
| 540 | + return $var; |
| 541 | + }, |
| 542 | + |
| 543 | + xml => \&Bugzilla::Util::xml_quote , |
| 544 | + |
| 545 | + # This filter escapes characters in a variable or value string for |
| 546 | + # use in a query string. It escapes all characters NOT in the |
| 547 | + # regex set: [a-zA-Z0-9_\-.]. The 'uri' filter should be used for |
| 548 | + # a full URL that may have characters that need encoding. |
| 549 | + url_quote => \&Bugzilla::Util::url_quote , |
| 550 | + |
| 551 | + # This filter is similar to url_quote but used a \ instead of a % |
| 552 | + # as prefix. In addition it replaces a ' ' by a '_'. |
| 553 | + css_class_quote => \&Bugzilla::Util::css_class_quote , |
| 554 | + |
| 555 | + quoteUrls => [ sub { |
| 556 | + my ($context, $bug, $already_wrapped) = @_; |
| 557 | + return sub { |
| 558 | + my $text = shift; |
| 559 | + return quoteUrls($text, $bug, $already_wrapped); |
| 560 | + }; |
| 561 | + }, |
| 562 | + 1 |
| 563 | + ], |
| 564 | + |
| 565 | + bug_link => [ sub { |
| 566 | + my ($context, $bug, $options) = @_; |
| 567 | + return sub { |
| 568 | + my $text = shift; |
| 569 | + return get_bug_link($bug, $text, $options); |
| 570 | + }; |
| 571 | + }, |
| 572 | + 1 |
| 573 | + ], |
| 574 | + |
| 575 | + bug_list_link => sub |
| 576 | + { |
| 577 | + my $buglist = shift; |
| 578 | + return join(", ", map(get_bug_link($_, $_), split(/ *, */, $buglist))); |
| 579 | + }, |
| 580 | + |
| 581 | + # In CSV, quotes are doubled, and any value containing a quote or a |
| 582 | + # comma is enclosed in quotes. |
| 583 | + csv => sub |
| 584 | + { |
| 585 | + my ($var) = @_; |
| 586 | + $var =~ s/\"/\"\"/g; |
| 587 | + if ($var !~ /^-?(\d+\.)?\d*$/) { |
| 588 | + $var = "\"$var\""; |
| 589 | + } |
| 590 | + return $var; |
| 591 | + } , |
| 592 | + |
| 593 | + # Format a filesize in bytes to a human readable value |
| 594 | + unitconvert => sub |
| 595 | + { |
| 596 | + my ($data) = @_; |
| 597 | + my $retval = ""; |
| 598 | + my %units = ( |
| 599 | + 'KB' => 1024, |
| 600 | + 'MB' => 1024 * 1024, |
| 601 | + 'GB' => 1024 * 1024 * 1024, |
| 602 | + ); |
| 603 | + |
| 604 | + if ($data < 1024) { |
| 605 | + return "$data bytes"; |
| 606 | + } |
| 607 | + else { |
| 608 | + my $u; |
| 609 | + foreach $u ('GB', 'MB', 'KB') { |
| 610 | + if ($data >= $units{$u}) { |
| 611 | + return sprintf("%.2f %s", $data/$units{$u}, $u); |
| 612 | + } |
| 613 | + } |
| 614 | + } |
| 615 | + }, |
| 616 | + |
| 617 | + # Format a time for display (more info in Bugzilla::Util) |
| 618 | + time => [ sub { |
| 619 | + my ($context, $format, $timezone) = @_; |
| 620 | + return sub { |
| 621 | + my $time = shift; |
| 622 | + return format_time($time, $format, $timezone); |
| 623 | + }; |
| 624 | + }, |
| 625 | + 1 |
| 626 | + ], |
| 627 | + |
| 628 | + # Bug 120030: Override html filter to obscure the '@' in user |
| 629 | + # visible strings. |
| 630 | + # Bug 319331: Handle BiDi disruptions. |
| 631 | + html => sub { |
| 632 | + my ($var) = Template::Filters::html_filter(@_); |
| 633 | + # Obscure '@'. |
| 634 | + $var =~ s/\@/\@/g; |
| 635 | + if (Bugzilla->params->{'utf8'}) { |
| 636 | + # Remove the following characters because they're |
| 637 | + # influencing BiDi: |
| 638 | + # -------------------------------------------------------- |
| 639 | + # |Code |Name |UTF-8 representation| |
| 640 | + # |------|--------------------------|--------------------| |
| 641 | + # |U+202a|Left-To-Right Embedding |0xe2 0x80 0xaa | |
| 642 | + # |U+202b|Right-To-Left Embedding |0xe2 0x80 0xab | |
| 643 | + # |U+202c|Pop Directional Formatting|0xe2 0x80 0xac | |
| 644 | + # |U+202d|Left-To-Right Override |0xe2 0x80 0xad | |
| 645 | + # |U+202e|Right-To-Left Override |0xe2 0x80 0xae | |
| 646 | + # -------------------------------------------------------- |
| 647 | + # |
| 648 | + # The following are characters influencing BiDi, too, but |
| 649 | + # they can be spared from filtering because they don't |
| 650 | + # influence more than one character right or left: |
| 651 | + # -------------------------------------------------------- |
| 652 | + # |Code |Name |UTF-8 representation| |
| 653 | + # |------|--------------------------|--------------------| |
| 654 | + # |U+200e|Left-To-Right Mark |0xe2 0x80 0x8e | |
| 655 | + # |U+200f|Right-To-Left Mark |0xe2 0x80 0x8f | |
| 656 | + # -------------------------------------------------------- |
| 657 | + $var =~ s/[\x{202a}-\x{202e}]//g; |
| 658 | + } |
| 659 | + return $var; |
| 660 | + }, |
| 661 | + |
| 662 | + html_light => \&Bugzilla::Util::html_light_quote, |
| 663 | + |
| 664 | + email => \&Bugzilla::Util::email_filter, |
| 665 | + |
| 666 | + # iCalendar contentline filter |
| 667 | + ics => [ sub { |
| 668 | + my ($context, @args) = @_; |
| 669 | + return sub { |
| 670 | + my ($var) = shift; |
| 671 | + my ($par) = shift @args; |
| 672 | + my ($output) = ""; |
| 673 | + |
| 674 | + $var =~ s/[\r\n]/ /g; |
| 675 | + $var =~ s/([;\\\",])/\\$1/g; |
| 676 | + |
| 677 | + if ($par) { |
| 678 | + $output = sprintf("%s:%s", $par, $var); |
| 679 | + } else { |
| 680 | + $output = $var; |
| 681 | + } |
| 682 | + |
| 683 | + $output =~ s/(.{75,75})/$1\n /g; |
| 684 | + |
| 685 | + return $output; |
| 686 | + }; |
| 687 | + }, |
| 688 | + 1 |
| 689 | + ], |
| 690 | + |
| 691 | + # Note that using this filter is even more dangerous than |
| 692 | + # using "none," and you should only use it when you're SURE |
| 693 | + # the output won't be displayed directly to a web browser. |
| 694 | + txt => sub { |
| 695 | + my ($var) = @_; |
| 696 | + # Trivial HTML tag remover |
| 697 | + $var =~ s/<[^>]*>//g; |
| 698 | + # And this basically reverses the html filter. |
| 699 | + $var =~ s/\@/@/g; |
| 700 | + $var =~ s/\</</g; |
| 701 | + $var =~ s/\>/>/g; |
| 702 | + $var =~ s/\"/\"/g; |
| 703 | + $var =~ s/\&/\&/g; |
| 704 | + # Now remove extra whitespace, and wrap it to 72 characters. |
| 705 | + my $collapse_filter = $Template::Filters::FILTERS->{collapse}; |
| 706 | + $var = $collapse_filter->($var); |
| 707 | + $var = wrap_comment($var, 72); |
| 708 | + return $var; |
| 709 | + }, |
| 710 | + |
| 711 | + # Wrap a displayed comment to the appropriate length |
| 712 | + wrap_comment => [ |
| 713 | + sub { |
| 714 | + my ($context, $cols) = @_; |
| 715 | + return sub { wrap_comment($_[0], $cols) } |
| 716 | + }, 1], |
| 717 | + |
| 718 | + # We force filtering of every variable in key security-critical |
| 719 | + # places; we have a none filter for people to use when they |
| 720 | + # really, really don't want a variable to be changed. |
| 721 | + none => sub { return $_[0]; } , |
| 722 | + }, |
| 723 | + |
| 724 | + PLUGIN_BASE => 'Bugzilla::Template::Plugin', |
| 725 | + |
| 726 | + CONSTANTS => _load_constants(), |
| 727 | + |
| 728 | + # Default variables for all templates |
| 729 | + VARIABLES => { |
| 730 | + # Function for retrieving global parameters. |
| 731 | + 'Param' => sub { return Bugzilla->params->{$_[0]}; }, |
| 732 | + |
| 733 | + # Function to create date strings |
| 734 | + 'time2str' => \&Date::Format::time2str, |
| 735 | + |
| 736 | + # Generic linear search function |
| 737 | + 'lsearch' => \&Bugzilla::Util::lsearch, |
| 738 | + |
| 739 | + # Currently logged in user, if any |
| 740 | + # If an sudo session is in progress, this is the user we're faking |
| 741 | + 'user' => sub { return Bugzilla->user; }, |
| 742 | + |
| 743 | + # If an sudo session is in progress, this is the user who |
| 744 | + # started the session. |
| 745 | + 'sudoer' => sub { return Bugzilla->sudoer; }, |
| 746 | + |
| 747 | + # SendBugMail - sends mail about a bug, using Bugzilla::BugMail.pm |
| 748 | + 'SendBugMail' => sub { |
| 749 | + my ($id, $mailrecipients) = (@_); |
| 750 | + require Bugzilla::BugMail; |
| 751 | + Bugzilla::BugMail::Send($id, $mailrecipients); |
| 752 | + }, |
| 753 | + |
| 754 | + # Allow templates to access the "corect" URLBase value |
| 755 | + 'urlbase' => sub { return Bugzilla::Util::correct_urlbase(); }, |
| 756 | + |
| 757 | + # Allow templates to access docs url with users' preferred language |
| 758 | + 'docs_urlbase' => sub { |
| 759 | + my ($language) = include_languages(); |
| 760 | + my $docs_urlbase = Bugzilla->params->{'docs_urlbase'}; |
| 761 | + $docs_urlbase =~ s/\%lang\%/$language/; |
| 762 | + return $docs_urlbase; |
| 763 | + }, |
| 764 | + |
| 765 | + # Allow templates to generate a token themselves. |
| 766 | + 'issue_hash_token' => \&Bugzilla::Token::issue_hash_token, |
| 767 | + |
| 768 | + # A way for all templates to get at Field data, cached. |
| 769 | + 'bug_fields' => sub { |
| 770 | + my $cache = Bugzilla->request_cache; |
| 771 | + $cache->{template_bug_fields} ||= |
| 772 | + { map { $_->name => $_ } Bugzilla->get_fields() }; |
| 773 | + return $cache->{template_bug_fields}; |
| 774 | + }, |
| 775 | + |
| 776 | + # These don't work as normal constants. |
| 777 | + DB_MODULE => \&Bugzilla::Constants::DB_MODULE, |
| 778 | + REQUIRED_MODULES => |
| 779 | + \&Bugzilla::Install::Requirements::REQUIRED_MODULES, |
| 780 | + OPTIONAL_MODULES => sub { |
| 781 | + my @optional = @{OPTIONAL_MODULES()}; |
| 782 | + @optional = sort {$a->{feature} cmp $b->{feature}} |
| 783 | + @optional; |
| 784 | + return \@optional; |
| 785 | + }, |
| 786 | + }, |
| 787 | + |
| 788 | + }) || die("Template creation failed: " . $class->error()); |
| 789 | +} |
| 790 | + |
| 791 | +# Used as part of the two subroutines below. |
| 792 | +our (%_templates_to_precompile, $_current_path); |
| 793 | + |
| 794 | +sub precompile_templates { |
| 795 | + my ($output) = @_; |
| 796 | + |
| 797 | + # Remove the compiled templates. |
| 798 | + my $datadir = bz_locations()->{'datadir'}; |
| 799 | + if (-e "$datadir/template") { |
| 800 | + print install_string('template_removing_dir') . "\n" if $output; |
| 801 | + |
| 802 | + # XXX This frequently fails if the webserver made the files, because |
| 803 | + # then the webserver owns the directories. We could fix that by |
| 804 | + # doing a chmod/chown on all the directories here. |
| 805 | + rmtree("$datadir/template"); |
| 806 | + |
| 807 | + # Check that the directory was really removed |
| 808 | + if(-e "$datadir/template") { |
| 809 | + print "\n\n"; |
| 810 | + print "The directory '$datadir/template' could not be removed.\n"; |
| 811 | + print "Please remove it manually and rerun checksetup.pl.\n\n"; |
| 812 | + exit; |
| 813 | + } |
| 814 | + } |
| 815 | + |
| 816 | + print install_string('template_precompile') if $output; |
| 817 | + |
| 818 | + my $templatedir = bz_locations()->{'templatedir'}; |
| 819 | + # Don't hang on templates which use the CGI library |
| 820 | + eval("use CGI qw(-no_debug)"); |
| 821 | + |
| 822 | + my $dir_reader = new IO::Dir($templatedir) || die "$templatedir: $!"; |
| 823 | + my @language_dirs = grep { /^[a-z-]+$/i } $dir_reader->read; |
| 824 | + $dir_reader->close; |
| 825 | + |
| 826 | + foreach my $dir (@language_dirs) { |
| 827 | + next if ($dir eq 'CVS'); |
| 828 | + -d "$templatedir/$dir/default" || -d "$templatedir/$dir/custom" |
| 829 | + || next; |
| 830 | + local $ENV{'HTTP_ACCEPT_LANGUAGE'} = $dir; |
| 831 | + my $template = Bugzilla::Template->create(clean_cache => 1); |
| 832 | + |
| 833 | + # Precompile all the templates found in all the directories. |
| 834 | + %_templates_to_precompile = (); |
| 835 | + foreach my $subdir (qw(custom extension default), bz_locations()->{'project'}) { |
| 836 | + next unless $subdir; # If 'project' is empty. |
| 837 | + $_current_path = File::Spec->catdir($templatedir, $dir, $subdir); |
| 838 | + next unless -d $_current_path; |
| 839 | + # Traverse the template hierarchy. |
| 840 | + find({ wanted => \&_precompile_push, no_chdir => 1 }, $_current_path); |
| 841 | + } |
| 842 | + # The sort isn't totally necessary, but it makes debugging easier |
| 843 | + # by making the templates always be compiled in the same order. |
| 844 | + foreach my $file (sort keys %_templates_to_precompile) { |
| 845 | + # Compile the template but throw away the result. This has the side- |
| 846 | + # effect of writing the compiled version to disk. |
| 847 | + $template->context->template($file); |
| 848 | + } |
| 849 | + } |
| 850 | + |
| 851 | + # Under mod_perl, we look for templates using the absolute path of the |
| 852 | + # template directory, which causes Template Toolkit to look for their |
| 853 | + # *compiled* versions using the full absolute path under the data/template |
| 854 | + # directory. (Like data/template/var/www/html/mod_perl/.) To avoid |
| 855 | + # re-compiling templates under mod_perl, we symlink to the |
| 856 | + # already-compiled templates. This doesn't work on Windows. |
| 857 | + if (!ON_WINDOWS) { |
| 858 | + my $abs_root = dirname(abs_path($templatedir)); |
| 859 | + my $todir = "$datadir/template$abs_root"; |
| 860 | + mkpath($todir); |
| 861 | + # We use abs2rel so that the symlink will look like |
| 862 | + # "../../../../template" which works, while just |
| 863 | + # "data/template/template/" doesn't work. |
| 864 | + my $fromdir = File::Spec->abs2rel("$datadir/template/template", $todir); |
| 865 | + # We eval for systems that can't symlink at all, where "symlink" |
| 866 | + # throws a fatal error. |
| 867 | + eval { symlink($fromdir, "$todir/template") |
| 868 | + or warn "Failed to symlink from $fromdir to $todir: $!" }; |
| 869 | + } |
| 870 | + |
| 871 | + # If anything created a Template object before now, clear it out. |
| 872 | + delete Bugzilla->request_cache->{template}; |
| 873 | + # This is the single variable used to precompile templates, |
| 874 | + # which needs to be cleared as well. |
| 875 | + delete Bugzilla->request_cache->{template_include_path_}; |
| 876 | + |
| 877 | + print install_string('done') . "\n" if $output; |
| 878 | +} |
| 879 | + |
| 880 | +# Helper for precompile_templates |
| 881 | +sub _precompile_push { |
| 882 | + my $name = $File::Find::name; |
| 883 | + return if (-d $name); |
| 884 | + return if ($name =~ /\/CVS\//); |
| 885 | + return if ($name !~ /\.tmpl$/); |
| 886 | + |
| 887 | + $name =~ s/\Q$_current_path\E\///; |
| 888 | + $_templates_to_precompile{$name} = 1; |
| 889 | +} |
| 890 | + |
| 891 | +1; |
| 892 | + |
| 893 | +__END__ |
| 894 | + |
| 895 | +=head1 NAME |
| 896 | + |
| 897 | +Bugzilla::Template - Wrapper around the Template Toolkit C<Template> object |
| 898 | + |
| 899 | +=head1 SYNOPSIS |
| 900 | + |
| 901 | + my $template = Bugzilla::Template->create; |
| 902 | + my $format = $template->get_format("foo/bar", |
| 903 | + scalar($cgi->param('format')), |
| 904 | + scalar($cgi->param('ctype'))); |
| 905 | + |
| 906 | +=head1 DESCRIPTION |
| 907 | + |
| 908 | +This is basically a wrapper so that the correct arguments get passed into |
| 909 | +the C<Template> constructor. |
| 910 | + |
| 911 | +It should not be used directly by scripts or modules - instead, use |
| 912 | +C<Bugzilla-E<gt>instance-E<gt>template> to get an already created module. |
| 913 | + |
| 914 | +=head1 SUBROUTINES |
| 915 | + |
| 916 | +=over |
| 917 | + |
| 918 | +=item C<precompile_templates($output)> |
| 919 | + |
| 920 | +Description: Compiles all of Bugzilla's templates in every language. |
| 921 | + Used mostly by F<checksetup.pl>. |
| 922 | + |
| 923 | +Params: C<$output> - C<true> if you want the function to print |
| 924 | + out information about what it's doing. |
| 925 | + |
| 926 | +Returns: nothing |
| 927 | + |
| 928 | +=back |
| 929 | + |
| 930 | +=head1 METHODS |
| 931 | + |
| 932 | +=over |
| 933 | + |
| 934 | +=item C<get_format($file, $format, $ctype)> |
| 935 | + |
| 936 | + Description: Construct a format object from URL parameters. |
| 937 | + |
| 938 | + Params: $file - Name of the template to display. |
| 939 | + $format - When the template exists under several formats |
| 940 | + (e.g. table or graph), specify the one to choose. |
| 941 | + $ctype - Content type, see Bugzilla::Constants::contenttypes. |
| 942 | + |
| 943 | + Returns: A format object. |
| 944 | + |
| 945 | +=back |
| 946 | + |
| 947 | +=head1 SEE ALSO |
| 948 | + |
| 949 | +L<Bugzilla>, L<Template> |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/Bugzilla/Template.pm |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 950 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/Bugzilla/BugMail.pm |
— | — | @@ -0,0 +1,700 @@ |
| 2 | +# -*- Mode: perl; indent-tabs-mode: nil -*- |
| 3 | +# |
| 4 | +# The contents of this file are subject to the Mozilla Public |
| 5 | +# License Version 1.1 (the "License"); you may not use this file |
| 6 | +# except in compliance with the License. You may obtain a copy of |
| 7 | +# the License at http://www.mozilla.org/MPL/ |
| 8 | +# |
| 9 | +# Software distributed under the License is distributed on an "AS |
| 10 | +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 | +# implied. See the License for the specific language governing |
| 12 | +# rights and limitations under the License. |
| 13 | +# |
| 14 | +# The Original Code is the Bugzilla Bug Tracking System. |
| 15 | +# |
| 16 | +# The Initial Developer of the Original Code is Netscape Communications |
| 17 | +# Corporation. Portions created by Netscape are |
| 18 | +# Copyright (C) 1998 Netscape Communications Corporation. All |
| 19 | +# Rights Reserved. |
| 20 | +# |
| 21 | +# Contributor(s): Terry Weissman <terry@mozilla.org>, |
| 22 | +# Bryce Nesbitt <bryce-mozilla@nextbus.com> |
| 23 | +# Dan Mosedale <dmose@mozilla.org> |
| 24 | +# Alan Raetz <al_raetz@yahoo.com> |
| 25 | +# Jacob Steenhagen <jake@actex.net> |
| 26 | +# Matthew Tuck <matty@chariot.net.au> |
| 27 | +# Bradley Baetz <bbaetz@student.usyd.edu.au> |
| 28 | +# J. Paul Reed <preed@sigkill.com> |
| 29 | +# Gervase Markham <gerv@gerv.net> |
| 30 | +# Byron Jones <bugzilla@glob.com.au> |
| 31 | + |
| 32 | +use strict; |
| 33 | + |
| 34 | +package Bugzilla::BugMail; |
| 35 | + |
| 36 | +use Bugzilla::Error; |
| 37 | +use Bugzilla::User; |
| 38 | +use Bugzilla::Constants; |
| 39 | +use Bugzilla::Util; |
| 40 | +use Bugzilla::Bug; |
| 41 | +use Bugzilla::Classification; |
| 42 | +use Bugzilla::Product; |
| 43 | +use Bugzilla::Component; |
| 44 | +use Bugzilla::Status; |
| 45 | +use Bugzilla::Mailer; |
| 46 | + |
| 47 | +use Date::Parse; |
| 48 | +use Date::Format; |
| 49 | + |
| 50 | +use constant FORMAT_TRIPLE => "%19s|%-28s|%-28s"; |
| 51 | +use constant FORMAT_3_SIZE => [19,28,28]; |
| 52 | +use constant FORMAT_DOUBLE => "%19s %-55s"; |
| 53 | +use constant FORMAT_2_SIZE => [19,55]; |
| 54 | + |
| 55 | +use constant BIT_DIRECT => 1; |
| 56 | +use constant BIT_WATCHING => 2; |
| 57 | + |
| 58 | +# We need these strings for the X-Bugzilla-Reasons header |
| 59 | +# Note: this hash uses "," rather than "=>" to avoid auto-quoting of the LHS. |
| 60 | +use constant REL_NAMES => { |
| 61 | + REL_ASSIGNEE , "AssignedTo", |
| 62 | + REL_REPORTER , "Reporter", |
| 63 | + REL_QA , "QAcontact", |
| 64 | + REL_CC , "CC", |
| 65 | + REL_VOTER , "Voter", |
| 66 | + REL_GLOBAL_WATCHER, "GlobalWatcher" |
| 67 | +}; |
| 68 | + |
| 69 | +# We use this instead of format because format doesn't deal well with |
| 70 | +# multi-byte languages. |
| 71 | +sub multiline_sprintf { |
| 72 | + my ($format, $args, $sizes) = @_; |
| 73 | + my @parts; |
| 74 | + my @my_sizes = @$sizes; # Copy this so we don't modify the input array. |
| 75 | + foreach my $string (@$args) { |
| 76 | + my $size = shift @my_sizes; |
| 77 | + my @pieces = split("\n", wrap_hard($string, $size)); |
| 78 | + push(@parts, \@pieces); |
| 79 | + } |
| 80 | + |
| 81 | + my $formatted; |
| 82 | + while (1) { |
| 83 | + # Get the first item of each part. |
| 84 | + my @line = map { shift @$_ } @parts; |
| 85 | + # If they're all undef, we're done. |
| 86 | + last if !grep { defined $_ } @line; |
| 87 | + # Make any single undef item into '' |
| 88 | + @line = map { defined $_ ? $_ : '' } @line; |
| 89 | + # And append a formatted line |
| 90 | + $formatted .= sprintf($format, @line); |
| 91 | + # Remove trailing spaces, or they become lots of =20's in |
| 92 | + # quoted-printable emails. |
| 93 | + $formatted =~ s/\s+$//; |
| 94 | + $formatted .= "\n"; |
| 95 | + } |
| 96 | + return $formatted; |
| 97 | +} |
| 98 | + |
| 99 | +sub three_columns { |
| 100 | + return multiline_sprintf(FORMAT_TRIPLE, \@_, FORMAT_3_SIZE); |
| 101 | +} |
| 102 | + |
| 103 | +# This is a bit of a hack, basically keeping the old system() |
| 104 | +# cmd line interface. Should clean this up at some point. |
| 105 | +# |
| 106 | +# args: bug_id, and an optional hash ref which may have keys for: |
| 107 | +# changer, owner, qa, reporter, cc |
| 108 | +# Optional hash contains values of people which will be forced to those |
| 109 | +# roles when the email is sent. |
| 110 | +# All the names are email addresses, not userids |
| 111 | +# values are scalars, except for cc, which is a list |
| 112 | +# This hash usually comes from the "mailrecipients" var in a template call. |
| 113 | +sub Send { |
| 114 | + my ($id, $forced) = (@_); |
| 115 | + |
| 116 | + my @headerlist; |
| 117 | + my %defmailhead; |
| 118 | + my %fielddescription; |
| 119 | + |
| 120 | + my $msg = ""; |
| 121 | + |
| 122 | + my $dbh = Bugzilla->dbh; |
| 123 | + |
| 124 | + # XXX - These variables below are useless. We could use field object |
| 125 | + # methods directly. But we first have to implement a cache in |
| 126 | + # Bugzilla->get_fields to avoid querying the DB all the time. |
| 127 | + foreach my $field (Bugzilla->get_fields({obsolete => 0})) { |
| 128 | + push(@headerlist, $field->name); |
| 129 | + $defmailhead{$field->name} = $field->in_new_bugmail; |
| 130 | + $fielddescription{$field->name} = $field->description; |
| 131 | + } |
| 132 | + |
| 133 | + my %values = %{$dbh->selectrow_hashref( |
| 134 | + 'SELECT ' . join(',', editable_bug_fields()) . ', reporter, |
| 135 | + lastdiffed AS start_time, LOCALTIMESTAMP(0) AS end_time |
| 136 | + FROM bugs WHERE bug_id = ?', |
| 137 | + undef, $id)}; |
| 138 | + |
| 139 | + my $product = new Bugzilla::Product($values{product_id}); |
| 140 | + $values{product} = $product->name; |
| 141 | + if (Bugzilla->params->{'useclassification'}) { |
| 142 | + $values{classification} = Bugzilla::Classification->new($product->classification_id)->name; |
| 143 | + } |
| 144 | + my $component = new Bugzilla::Component($values{component_id}); |
| 145 | + $values{component} = $component->name; |
| 146 | + |
| 147 | + my ($start, $end) = ($values{start_time}, $values{end_time}); |
| 148 | + |
| 149 | + # User IDs of people in various roles. More than one person can 'have' a |
| 150 | + # role, if the person in that role has changed, or people are watching. |
| 151 | + my $reporter = $values{'reporter'}; |
| 152 | + my @assignees = ($values{'assigned_to'}); |
| 153 | + my @qa_contacts = ($values{'qa_contact'}); |
| 154 | + |
| 155 | + my $cc_users = $dbh->selectall_arrayref( |
| 156 | + "SELECT cc.who, profiles.login_name |
| 157 | + FROM cc |
| 158 | + INNER JOIN profiles |
| 159 | + ON cc.who = profiles.userid |
| 160 | + WHERE bug_id = ?", |
| 161 | + undef, $id); |
| 162 | + |
| 163 | + my (@ccs, @cc_login_names); |
| 164 | + foreach my $cc_user (@$cc_users) { |
| 165 | + my ($user_id, $user_login) = @$cc_user; |
| 166 | + push (@ccs, $user_id); |
| 167 | + push (@cc_login_names, $user_login); |
| 168 | + } |
| 169 | + |
| 170 | + # Include the people passed in as being in particular roles. |
| 171 | + # This can include people who used to hold those roles. |
| 172 | + # At this point, we don't care if there are duplicates in these arrays. |
| 173 | + my $changer = $forced->{'changer'}; |
| 174 | + if ($forced->{'owner'}) { |
| 175 | + push (@assignees, login_to_id($forced->{'owner'}, THROW_ERROR)); |
| 176 | + } |
| 177 | + |
| 178 | + if ($forced->{'qacontact'}) { |
| 179 | + push (@qa_contacts, login_to_id($forced->{'qacontact'}, THROW_ERROR)); |
| 180 | + } |
| 181 | + |
| 182 | + if ($forced->{'cc'}) { |
| 183 | + foreach my $cc (@{$forced->{'cc'}}) { |
| 184 | + push(@ccs, login_to_id($cc, THROW_ERROR)); |
| 185 | + } |
| 186 | + } |
| 187 | + |
| 188 | + # Convert to names, for later display |
| 189 | + $values{'changer'} = $changer; |
| 190 | + # If no changer is specified, then it has no name. |
| 191 | + if ($changer) { |
| 192 | + $values{'changername'} = Bugzilla::User->new({name => $changer})->name; |
| 193 | + } |
| 194 | + $values{'assigned_to'} = user_id_to_login($values{'assigned_to'}); |
| 195 | + $values{'reporter'} = user_id_to_login($values{'reporter'}); |
| 196 | + if ($values{'qa_contact'}) { |
| 197 | + $values{'qa_contact'} = user_id_to_login($values{'qa_contact'}); |
| 198 | + } |
| 199 | + $values{'cc'} = join(', ', @cc_login_names); |
| 200 | + $values{'estimated_time'} = format_time_decimal($values{'estimated_time'}); |
| 201 | + |
| 202 | + if ($values{'deadline'}) { |
| 203 | + $values{'deadline'} = time2str("%Y-%m-%d", str2time($values{'deadline'})); |
| 204 | + } |
| 205 | + |
| 206 | + my $dependslist = $dbh->selectcol_arrayref( |
| 207 | + 'SELECT dependson FROM dependencies |
| 208 | + WHERE blocked = ? ORDER BY dependson', |
| 209 | + undef, ($id)); |
| 210 | + |
| 211 | + $values{'dependson'} = join(",", @$dependslist); |
| 212 | + |
| 213 | + my $blockedlist = $dbh->selectcol_arrayref( |
| 214 | + 'SELECT blocked FROM dependencies |
| 215 | + WHERE dependson = ? ORDER BY blocked', |
| 216 | + undef, ($id)); |
| 217 | + |
| 218 | + $values{'blocked'} = join(",", @$blockedlist); |
| 219 | + |
| 220 | + my $grouplist = $dbh->selectcol_arrayref( |
| 221 | + ' SELECT name FROM groups |
| 222 | + INNER JOIN bug_group_map |
| 223 | + ON groups.id = bug_group_map.group_id |
| 224 | + AND bug_group_map.bug_id = ?', |
| 225 | + undef, ($id)); |
| 226 | + |
| 227 | + $values{'bug_group'} = join(', ', @$grouplist); |
| 228 | + |
| 229 | + my @args = ($id); |
| 230 | + |
| 231 | + # If lastdiffed is NULL, then we don't limit the search on time. |
| 232 | + my $when_restriction = ''; |
| 233 | + if ($start) { |
| 234 | + $when_restriction = ' AND bug_when > ? AND bug_when <= ?'; |
| 235 | + push @args, ($start, $end); |
| 236 | + } |
| 237 | + |
| 238 | + my $diffs = $dbh->selectall_arrayref( |
| 239 | + "SELECT profiles.login_name, profiles.realname, fielddefs.description, |
| 240 | + bugs_activity.bug_when, bugs_activity.removed, |
| 241 | + bugs_activity.added, bugs_activity.attach_id, fielddefs.name |
| 242 | + FROM bugs_activity |
| 243 | + INNER JOIN fielddefs |
| 244 | + ON fielddefs.id = bugs_activity.fieldid |
| 245 | + INNER JOIN profiles |
| 246 | + ON profiles.userid = bugs_activity.who |
| 247 | + WHERE bugs_activity.bug_id = ? |
| 248 | + $when_restriction |
| 249 | + ORDER BY bugs_activity.bug_when", undef, @args); |
| 250 | + |
| 251 | + my @new_depbugs; |
| 252 | + my $difftext = ""; |
| 253 | + my $diffheader = ""; |
| 254 | + my @diffparts; |
| 255 | + my $lastwho = ""; |
| 256 | + my $fullwho; |
| 257 | + my @changedfields; |
| 258 | + foreach my $ref (@$diffs) { |
| 259 | + my ($who, $whoname, $what, $when, $old, $new, $attachid, $fieldname) = (@$ref); |
| 260 | + my $diffpart = {}; |
| 261 | + if ($who ne $lastwho) { |
| 262 | + $lastwho = $who; |
| 263 | + $fullwho = $whoname ? "$whoname <$who>" : $who; |
| 264 | + $diffheader = "\n$fullwho changed:\n\n"; |
| 265 | + $diffheader .= three_columns("What ", "Removed", "Added"); |
| 266 | + $diffheader .= ('-' x 76) . "\n"; |
| 267 | + } |
| 268 | + $what =~ s/^(Attachment )?/Attachment #$attachid / if $attachid; |
| 269 | + if( $fieldname eq 'estimated_time' || |
| 270 | + $fieldname eq 'remaining_time' ) { |
| 271 | + $old = format_time_decimal($old); |
| 272 | + $new = format_time_decimal($new); |
| 273 | + } |
| 274 | + if ($fieldname eq 'dependson') { |
| 275 | + push(@new_depbugs, grep {$_ =~ /^\d+$/} split(/[\s,]+/, $new)); |
| 276 | + } |
| 277 | + if ($attachid) { |
| 278 | + ($diffpart->{'isprivate'}) = $dbh->selectrow_array( |
| 279 | + 'SELECT isprivate FROM attachments WHERE attach_id = ?', |
| 280 | + undef, ($attachid)); |
| 281 | + } |
| 282 | + $difftext = three_columns($what, $old, $new); |
| 283 | + $diffpart->{'header'} = $diffheader; |
| 284 | + $diffpart->{'fieldname'} = $fieldname; |
| 285 | + $diffpart->{'text'} = $difftext; |
| 286 | + push(@diffparts, $diffpart); |
| 287 | + push(@changedfields, $what); |
| 288 | + } |
| 289 | + $values{'changed_fields'} = join(' ', @changedfields); |
| 290 | + |
| 291 | + my @depbugs; |
| 292 | + my $deptext = ""; |
| 293 | + # Do not include data about dependent bugs when they have just been added. |
| 294 | + # Completely skip checking for dependent bugs on bug creation as all |
| 295 | + # dependencies bugs will just have been added. |
| 296 | + if ($start) { |
| 297 | + my $dep_restriction = ""; |
| 298 | + if (scalar @new_depbugs) { |
| 299 | + $dep_restriction = "AND bugs_activity.bug_id NOT IN (" . |
| 300 | + join(", ", @new_depbugs) . ")"; |
| 301 | + } |
| 302 | + |
| 303 | + my $dependency_diffs = $dbh->selectall_arrayref( |
| 304 | + "SELECT bugs_activity.bug_id, bugs.short_desc, fielddefs.name, |
| 305 | + bugs_activity.removed, bugs_activity.added |
| 306 | + FROM bugs_activity |
| 307 | + INNER JOIN bugs |
| 308 | + ON bugs.bug_id = bugs_activity.bug_id |
| 309 | + INNER JOIN dependencies |
| 310 | + ON bugs_activity.bug_id = dependencies.dependson |
| 311 | + INNER JOIN fielddefs |
| 312 | + ON fielddefs.id = bugs_activity.fieldid |
| 313 | + WHERE dependencies.blocked = ? |
| 314 | + AND (fielddefs.name = 'bug_status' |
| 315 | + OR fielddefs.name = 'resolution') |
| 316 | + $when_restriction |
| 317 | + $dep_restriction |
| 318 | + ORDER BY bugs_activity.bug_when, bugs.bug_id", undef, @args); |
| 319 | + |
| 320 | + my $thisdiff = ""; |
| 321 | + my $lastbug = ""; |
| 322 | + my $interestingchange = 0; |
| 323 | + foreach my $dependency_diff (@$dependency_diffs) { |
| 324 | + my ($depbug, $summary, $what, $old, $new) = @$dependency_diff; |
| 325 | + |
| 326 | + if ($depbug ne $lastbug) { |
| 327 | + if ($interestingchange) { |
| 328 | + $deptext .= $thisdiff; |
| 329 | + } |
| 330 | + $lastbug = $depbug; |
| 331 | + $thisdiff = |
| 332 | + "\nBug $id depends on bug $depbug, which changed state.\n\n" . |
| 333 | + "Bug $depbug Summary: $summary\n" . |
| 334 | + correct_urlbase() . "show_bug.cgi?id=$depbug\n\n"; |
| 335 | + $thisdiff .= three_columns("What ", "Old Value", "New Value"); |
| 336 | + $thisdiff .= ('-' x 76) . "\n"; |
| 337 | + $interestingchange = 0; |
| 338 | + } |
| 339 | + $thisdiff .= three_columns($fielddescription{$what}, $old, $new); |
| 340 | + if ($what eq 'bug_status' |
| 341 | + && is_open_state($old) ne is_open_state($new)) |
| 342 | + { |
| 343 | + $interestingchange = 1; |
| 344 | + } |
| 345 | + push(@depbugs, $depbug); |
| 346 | + } |
| 347 | + |
| 348 | + if ($interestingchange) { |
| 349 | + $deptext .= $thisdiff; |
| 350 | + } |
| 351 | + $deptext = trim($deptext); |
| 352 | + |
| 353 | + if ($deptext) { |
| 354 | + my $diffpart = {}; |
| 355 | + $diffpart->{'text'} = "\n" . trim($deptext); |
| 356 | + push(@diffparts, $diffpart); |
| 357 | + } |
| 358 | + } |
| 359 | + |
| 360 | + my ($comments, $anyprivate) = get_comments_by_bug($id, $start, $end); |
| 361 | + |
| 362 | + ########################################################################### |
| 363 | + # Start of email filtering code |
| 364 | + ########################################################################### |
| 365 | + |
| 366 | + # A user_id => roles hash to keep track of people. |
| 367 | + my %recipients; |
| 368 | + my %watching; |
| 369 | + |
| 370 | + # Now we work out all the people involved with this bug, and note all of |
| 371 | + # the relationships in a hash. The keys are userids, the values are an |
| 372 | + # array of role constants. |
| 373 | + |
| 374 | + # Voters |
| 375 | + my $voters = $dbh->selectcol_arrayref( |
| 376 | + "SELECT who FROM votes WHERE bug_id = ?", undef, ($id)); |
| 377 | + |
| 378 | + $recipients{$_}->{+REL_VOTER} = BIT_DIRECT foreach (@$voters); |
| 379 | + |
| 380 | + # CCs |
| 381 | + $recipients{$_}->{+REL_CC} = BIT_DIRECT foreach (@ccs); |
| 382 | + |
| 383 | + # Reporter (there's only ever one) |
| 384 | + $recipients{$reporter}->{+REL_REPORTER} = BIT_DIRECT; |
| 385 | + |
| 386 | + # QA Contact |
| 387 | + if (Bugzilla->params->{'useqacontact'}) { |
| 388 | + foreach (@qa_contacts) { |
| 389 | + # QA Contact can be blank; ignore it if so. |
| 390 | + $recipients{$_}->{+REL_QA} = BIT_DIRECT if $_; |
| 391 | + } |
| 392 | + } |
| 393 | + |
| 394 | + # Assignee |
| 395 | + $recipients{$_}->{+REL_ASSIGNEE} = BIT_DIRECT foreach (@assignees); |
| 396 | + |
| 397 | + # The last relevant set of people are those who are being removed from |
| 398 | + # their roles in this change. We get their names out of the diffs. |
| 399 | + foreach my $ref (@$diffs) { |
| 400 | + my ($who, $whoname, $what, $when, $old, $new) = (@$ref); |
| 401 | + if ($old) { |
| 402 | + # You can't stop being the reporter, and mail isn't sent if you |
| 403 | + # remove your vote. |
| 404 | + # Ignore people whose user account has been deleted or renamed. |
| 405 | + if ($what eq "CC") { |
| 406 | + foreach my $cc_user (split(/[\s,]+/, $old)) { |
| 407 | + my $uid = login_to_id($cc_user); |
| 408 | + $recipients{$uid}->{+REL_CC} = BIT_DIRECT if $uid; |
| 409 | + } |
| 410 | + } |
| 411 | + elsif ($what eq "QAContact") { |
| 412 | + my $uid = login_to_id($old); |
| 413 | + $recipients{$uid}->{+REL_QA} = BIT_DIRECT if $uid; |
| 414 | + } |
| 415 | + elsif ($what eq "AssignedTo") { |
| 416 | + my $uid = login_to_id($old); |
| 417 | + $recipients{$uid}->{+REL_ASSIGNEE} = BIT_DIRECT if $uid; |
| 418 | + } |
| 419 | + } |
| 420 | + } |
| 421 | + |
| 422 | + # Find all those user-watching anyone on the current list, who is not |
| 423 | + # on it already themselves. |
| 424 | + my $involved = join(",", keys %recipients); |
| 425 | + |
| 426 | + my $userwatchers = |
| 427 | + $dbh->selectall_arrayref("SELECT watcher, watched FROM watch |
| 428 | + WHERE watched IN ($involved)"); |
| 429 | + |
| 430 | + # Mark these people as having the role of the person they are watching |
| 431 | + foreach my $watch (@$userwatchers) { |
| 432 | + while (my ($role, $bits) = each %{$recipients{$watch->[1]}}) { |
| 433 | + $recipients{$watch->[0]}->{$role} |= BIT_WATCHING |
| 434 | + if $bits & BIT_DIRECT; |
| 435 | + } |
| 436 | + push(@{$watching{$watch->[0]}}, $watch->[1]); |
| 437 | + } |
| 438 | + |
| 439 | + # Global watcher |
| 440 | + my @watchers = split(/[,\s]+/, Bugzilla->params->{'globalwatchers'}); |
| 441 | + foreach (@watchers) { |
| 442 | + my $watcher_id = login_to_id($_); |
| 443 | + next unless $watcher_id; |
| 444 | + #$recipients{$watcher_id}->{+REL_GLOBAL_WATCHER} = BIT_DIRECT; |
| 445 | + # Hack! Pretend global watchers are CCs so we can use their prefs |
| 446 | + # to for instance ignore CC-only mails. |
| 447 | + $recipients{$watcher_id}->{+REL_CC} = BIT_DIRECT; |
| 448 | + } |
| 449 | + |
| 450 | + # We now have a complete set of all the users, and their relationships to |
| 451 | + # the bug in question. However, we are not necessarily going to mail them |
| 452 | + # all - there are preferences, permissions checks and all sorts to do yet. |
| 453 | + my @sent; |
| 454 | + my @excluded; |
| 455 | + |
| 456 | + foreach my $user_id (keys %recipients) { |
| 457 | + my %rels_which_want; |
| 458 | + my $sent_mail = 0; |
| 459 | + |
| 460 | + my $user = new Bugzilla::User($user_id); |
| 461 | + # Deleted users must be excluded. |
| 462 | + next unless $user; |
| 463 | + |
| 464 | + if ($user->can_see_bug($id)) { |
| 465 | + # Go through each role the user has and see if they want mail in |
| 466 | + # that role. |
| 467 | + foreach my $relationship (keys %{$recipients{$user_id}}) { |
| 468 | + if ($user->wants_bug_mail($id, |
| 469 | + $relationship, |
| 470 | + $diffs, |
| 471 | + $comments, |
| 472 | + $deptext, |
| 473 | + $changer, |
| 474 | + !$start)) |
| 475 | + { |
| 476 | + $rels_which_want{$relationship} = |
| 477 | + $recipients{$user_id}->{$relationship}; |
| 478 | + } |
| 479 | + } |
| 480 | + } |
| 481 | + |
| 482 | + if (scalar(%rels_which_want)) { |
| 483 | + # So the user exists, can see the bug, and wants mail in at least |
| 484 | + # one role. But do we want to send it to them? |
| 485 | + |
| 486 | + # If we are using insiders, and the comment is private, only send |
| 487 | + # to insiders |
| 488 | + my $insider_ok = 1; |
| 489 | + $insider_ok = 0 if $anyprivate && !$user->is_insider; |
| 490 | + |
| 491 | + # We shouldn't send mail if this is a dependency mail (i.e. there |
| 492 | + # is something in @depbugs), and any of the depending bugs are not |
| 493 | + # visible to the user. This is to avoid leaking the summaries of |
| 494 | + # confidential bugs. |
| 495 | + my $dep_ok = 1; |
| 496 | + foreach my $dep_id (@depbugs) { |
| 497 | + if (!$user->can_see_bug($dep_id)) { |
| 498 | + $dep_ok = 0; |
| 499 | + last; |
| 500 | + } |
| 501 | + } |
| 502 | + |
| 503 | + # Make sure the user isn't in the nomail list, and the insider and |
| 504 | + # dep checks passed. |
| 505 | + if ($user->email_enabled && |
| 506 | + $insider_ok && |
| 507 | + $dep_ok) |
| 508 | + { |
| 509 | + # OK, OK, if we must. Email the user. |
| 510 | + $sent_mail = sendMail($user, |
| 511 | + \@headerlist, |
| 512 | + \%rels_which_want, |
| 513 | + \%values, |
| 514 | + \%defmailhead, |
| 515 | + \%fielddescription, |
| 516 | + \@diffparts, |
| 517 | + $comments, |
| 518 | + $anyprivate, |
| 519 | + ! $start, |
| 520 | + $id, |
| 521 | + exists $watching{$user_id} ? |
| 522 | + $watching{$user_id} : undef); |
| 523 | + } |
| 524 | + } |
| 525 | + |
| 526 | + if ($sent_mail) { |
| 527 | + push(@sent, $user->login); |
| 528 | + } |
| 529 | + else { |
| 530 | + push(@excluded, $user->login); |
| 531 | + } |
| 532 | + } |
| 533 | + |
| 534 | + $dbh->do('UPDATE bugs SET lastdiffed = ? WHERE bug_id = ?', |
| 535 | + undef, ($end, $id)); |
| 536 | + |
| 537 | + return {'sent' => \@sent, 'excluded' => \@excluded}; |
| 538 | +} |
| 539 | + |
| 540 | +sub sendMail { |
| 541 | + my ($user, $hlRef, $relRef, $valueRef, $dmhRef, $fdRef, |
| 542 | + $diffRef, $newcomments, $anyprivate, $isnew, |
| 543 | + $id, $watchingRef) = @_; |
| 544 | + |
| 545 | + my %values = %$valueRef; |
| 546 | + my @headerlist = @$hlRef; |
| 547 | + my %mailhead = %$dmhRef; |
| 548 | + my %fielddescription = %$fdRef; |
| 549 | + my @diffparts = @$diffRef; |
| 550 | + |
| 551 | + # Build difftext (the actions) by verifying the user should see them |
| 552 | + my $difftext = ""; |
| 553 | + my $diffheader = ""; |
| 554 | + my $add_diff; |
| 555 | + |
| 556 | + foreach my $diff (@diffparts) { |
| 557 | + $add_diff = 0; |
| 558 | + |
| 559 | + if (exists($diff->{'fieldname'}) && |
| 560 | + ($diff->{'fieldname'} eq 'estimated_time' || |
| 561 | + $diff->{'fieldname'} eq 'remaining_time' || |
| 562 | + $diff->{'fieldname'} eq 'work_time' || |
| 563 | + $diff->{'fieldname'} eq 'deadline')) |
| 564 | + { |
| 565 | + $add_diff = 1 if $user->is_timetracker; |
| 566 | + } elsif ($diff->{'isprivate'} |
| 567 | + && !$user->is_insider) |
| 568 | + { |
| 569 | + $add_diff = 0; |
| 570 | + } else { |
| 571 | + $add_diff = 1; |
| 572 | + } |
| 573 | + |
| 574 | + if ($add_diff) { |
| 575 | + if (exists($diff->{'header'}) && |
| 576 | + ($diffheader ne $diff->{'header'})) { |
| 577 | + $diffheader = $diff->{'header'}; |
| 578 | + $difftext .= $diffheader; |
| 579 | + } |
| 580 | + $difftext .= $diff->{'text'}; |
| 581 | + } |
| 582 | + } |
| 583 | + |
| 584 | + if ($difftext eq "" && !scalar(@$newcomments) && !$isnew) { |
| 585 | + # Whoops, no differences! |
| 586 | + return 0; |
| 587 | + } |
| 588 | + |
| 589 | + my $diffs = $difftext; |
| 590 | + # Remove extra newlines. |
| 591 | + $diffs =~ s/^\n+//s; $diffs =~ s/\n+$//s; |
| 592 | + if ($isnew) { |
| 593 | + my $head = ""; |
| 594 | + foreach my $f (@headerlist) { |
| 595 | + next unless $mailhead{$f}; |
| 596 | + my $value = $values{$f}; |
| 597 | + # If there isn't anything to show, don't include this header. |
| 598 | + next unless $value; |
| 599 | + # Only send estimated_time if it is enabled and the user is in the group. |
| 600 | + if (($f ne 'estimated_time' && $f ne 'deadline') || $user->is_timetracker) { |
| 601 | + my $desc = $fielddescription{$f}; |
| 602 | + $head .= multiline_sprintf(FORMAT_DOUBLE, ["$desc:", $value], |
| 603 | + FORMAT_2_SIZE); |
| 604 | + } |
| 605 | + } |
| 606 | + $diffs = $head . ($difftext ? "\n\n" : "") . $diffs; |
| 607 | + } |
| 608 | + |
| 609 | + my (@reasons, @reasons_watch); |
| 610 | + while (my ($relationship, $bits) = each %{$relRef}) { |
| 611 | + push(@reasons, $relationship) if ($bits & BIT_DIRECT); |
| 612 | + push(@reasons_watch, $relationship) if ($bits & BIT_WATCHING); |
| 613 | + } |
| 614 | + |
| 615 | + my @headerrel = map { REL_NAMES->{$_} } @reasons; |
| 616 | + my @watchingrel = map { REL_NAMES->{$_} } @reasons_watch; |
| 617 | + push(@headerrel, 'None') unless @headerrel; |
| 618 | + push(@watchingrel, 'None') unless @watchingrel; |
| 619 | + push @watchingrel, map { user_id_to_login($_) } @$watchingRef; |
| 620 | + |
| 621 | + my $vars = { |
| 622 | + isnew => $isnew, |
| 623 | + to => $user->email, |
| 624 | + bugid => $id, |
| 625 | + alias => Bugzilla->params->{'usebugaliases'} ? $values{'alias'} : "", |
| 626 | + classification => $values{'classification'}, |
| 627 | + product => $values{'product'}, |
| 628 | + comp => $values{'component'}, |
| 629 | + keywords => $values{'keywords'}, |
| 630 | + severity => $values{'bug_severity'}, |
| 631 | + status => $values{'bug_status'}, |
| 632 | + priority => $values{'priority'}, |
| 633 | + assignedto => $values{'assigned_to'}, |
| 634 | + assignedtoname => Bugzilla::User->new({name => $values{'assigned_to'}})->name, |
| 635 | + targetmilestone => $values{'target_milestone'}, |
| 636 | + changedfields => $values{'changed_fields'}, |
| 637 | + summary => $values{'short_desc'}, |
| 638 | + reasons => \@reasons, |
| 639 | + reasons_watch => \@reasons_watch, |
| 640 | + reasonsheader => join(" ", @headerrel), |
| 641 | + reasonswatchheader => join(" ", @watchingrel), |
| 642 | + changer => $values{'changer'}, |
| 643 | + changername => $values{'changername'}, |
| 644 | + reporter => $values{'reporter'}, |
| 645 | + reportername => Bugzilla::User->new({name => $values{'reporter'}})->name, |
| 646 | + diffs => $diffs, |
| 647 | + new_comments => $newcomments, |
| 648 | + threadingmarker => build_thread_marker($id, $user->id, $isnew), |
| 649 | + }; |
| 650 | + |
| 651 | + my $msg; |
| 652 | + my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'}); |
| 653 | + $template->process("email/newchangedmail.txt.tmpl", $vars, \$msg) |
| 654 | + || ThrowTemplateError($template->error()); |
| 655 | + Bugzilla->template_inner(""); |
| 656 | + |
| 657 | + MessageToMTA($msg); |
| 658 | + |
| 659 | + return 1; |
| 660 | +} |
| 661 | + |
| 662 | +# Get bug comments for the given period. |
| 663 | +sub get_comments_by_bug { |
| 664 | + my ($id, $start, $end) = @_; |
| 665 | + my $dbh = Bugzilla->dbh; |
| 666 | + |
| 667 | + my $result = ""; |
| 668 | + my $count = 0; |
| 669 | + my $anyprivate = 0; |
| 670 | + |
| 671 | + # $start will be undef for new bugs, and defined for pre-existing bugs. |
| 672 | + if ($start) { |
| 673 | + # If $start is not NULL, obtain the count-index |
| 674 | + # of this comment for the leading "Comment #xxx" line. |
| 675 | + $count = $dbh->selectrow_array('SELECT COUNT(*) FROM longdescs |
| 676 | + WHERE bug_id = ? AND bug_when <= ?', |
| 677 | + undef, ($id, $start)); |
| 678 | + } |
| 679 | + |
| 680 | + my $raw = 1; # Do not format comments which are not of type CMT_NORMAL. |
| 681 | + my $comments = Bugzilla::Bug::GetComments($id, "oldest_to_newest", $start, $end, $raw); |
| 682 | + my $attach_base = correct_urlbase() . 'attachment.cgi?id='; |
| 683 | + |
| 684 | + foreach my $comment (@$comments) { |
| 685 | + $comment->{count} = $count++; |
| 686 | + # If an attachment was created, then add an URL. (Note: the 'g'lobal |
| 687 | + # replace should work with comments with multiple attachments.) |
| 688 | + if ($comment->{body} =~ /Created an attachment \(/) { |
| 689 | + $comment->{body} =~ s/(Created an attachment \(id=([0-9]+)\))/$1\n --> \($attach_base$2\)/g; |
| 690 | + } |
| 691 | + $comment->{body} = $comment->{'already_wrapped'} ? $comment->{body} : wrap_comment($comment->{body}); |
| 692 | + } |
| 693 | + |
| 694 | + if (Bugzilla->params->{'insidergroup'}) { |
| 695 | + $anyprivate = 1 if scalar(grep {$_->{'isprivate'} > 0} @$comments); |
| 696 | + } |
| 697 | + |
| 698 | + return ($comments, $anyprivate); |
| 699 | +} |
| 700 | + |
| 701 | +1; |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/Bugzilla/BugMail.pm |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 702 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/site-navigation.html.tmpl |
— | — | @@ -0,0 +1,127 @@ |
| 2 | +[%# The contents of this file are subject to the Mozilla Public |
| 3 | + # License Version 1.1 (the "License"); you may not use this file |
| 4 | + # except in compliance with the License. You may obtain a copy of |
| 5 | + # the License at http://www.mozilla.org/MPL/ |
| 6 | + # |
| 7 | + # Software distributed under the License is distributed on an "AS |
| 8 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + # implied. See the License for the specific language governing |
| 10 | + # rights and limitations under the License. |
| 11 | + # |
| 12 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + # |
| 14 | + # The Initial Developer of the Original Code is Netscape Communications |
| 15 | + # Corporation. Portions created by Netscape are |
| 16 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + # Rights Reserved. |
| 18 | + # |
| 19 | + # Contributor(s): Toms Baugis <toms.baugis@tietoenator.com> |
| 20 | + # Gervase Markham <gerv@gerv.net> |
| 21 | + #%] |
| 22 | + |
| 23 | +[%# INTERFACE: |
| 24 | + # bug_list: list of integers. List of bug numbers of current query (if any). |
| 25 | + # bug.bug_id: integer. Number of current bug (for navigation purposes) |
| 26 | + #%] |
| 27 | + |
| 28 | +[% PROCESS global/variables.none.tmpl %] |
| 29 | + |
| 30 | +[% USE Bugzilla %] |
| 31 | +[% cgi = Bugzilla.cgi %] |
| 32 | + |
| 33 | +[% IF NOT (cgi.user_agent("MSIE [1-6]") OR cgi.user_agent("Mozilla/4")) %] |
| 34 | + <link rel="Top" href="[% urlbase FILTER html %]"> |
| 35 | + |
| 36 | + [%# *** Bug List Navigation *** %] |
| 37 | + [% IF bug_list && bug_list.size > 0 %] |
| 38 | + <link rel="Up" href="buglist.cgi?regetlastlist=1"> |
| 39 | + |
| 40 | + <link rel="First" href="show_bug.cgi?id=[% bug_list.first %]"> |
| 41 | + <link rel="Last" href="show_bug.cgi?id=[% bug_list.last %]"> |
| 42 | + |
| 43 | + [% IF bug && bug.bug_id %] |
| 44 | + [% current_bug_idx = lsearch(bug_list, bug.bug_id) %] |
| 45 | + [% IF current_bug_idx != -1 %] |
| 46 | + |
| 47 | + [% IF current_bug_idx > 0 %] |
| 48 | + [% prev_bug = current_bug_idx - 1 %] |
| 49 | + <link rel="Prev" href="show_bug.cgi?id=[% bug_list.$prev_bug %]"> |
| 50 | + [% END %] |
| 51 | + |
| 52 | + [% IF current_bug_idx + 1 < bug_list.size %] |
| 53 | + [% next_bug = current_bug_idx + 1 %] |
| 54 | + <link rel="Next" href="show_bug.cgi?id=[% bug_list.$next_bug %]"> |
| 55 | + [% END %] |
| 56 | + |
| 57 | + [% END %] |
| 58 | + [% END %] |
| 59 | + [% END %] |
| 60 | + |
| 61 | + [%# *** Attachment *** %] |
| 62 | + [% IF attachment && attachment.bug_id %] |
| 63 | + <link rel="Up" href="show_bug.cgi?id=[% attachment.bug_id FILTER none %]"> |
| 64 | + [% END %] |
| 65 | + |
| 66 | + |
| 67 | + [%# *** Dependencies, Votes, Activity, Print-version *** %] |
| 68 | + [% IF bug %] |
| 69 | + <link rel="Show" title="Dependency Tree" |
| 70 | + href="showdependencytree.cgi?id=[% bug.bug_id %]&hide_resolved=1"> |
| 71 | + [% IF Param('webdotbase') %] |
| 72 | + <link rel="Show" title="Dependency Graph" |
| 73 | + href="showdependencygraph.cgi?id=[% bug.bug_id %]"> |
| 74 | + [% END %] |
| 75 | + |
| 76 | + [% IF bug.use_votes %] |
| 77 | + <link rel="Show" title="Votes ([% bug.votes %])" |
| 78 | + href="votes.cgi?action=show_bug&bug_id=[% bug.bug_id %]"> |
| 79 | + [% END %] |
| 80 | + |
| 81 | + <link rel="Show" title="[% terms.Bug %] Activity" |
| 82 | + href="show_activity.cgi?id=[% bug.bug_id %]"> |
| 83 | + <link rel="Show" title="Printer-Friendly Version" |
| 84 | + href="show_bug.cgi?format=multiple&id=[% bug.bug_id %]"> |
| 85 | + [% END %] |
| 86 | + |
| 87 | + |
| 88 | + [%# *** Saved Searches *** %] |
| 89 | + [% IF user.showmybugslink %] |
| 90 | + [% user_login = user.login FILTER url_quote %] |
| 91 | + <link rel="Saved Searches" title="My [% terms.Bugs %]" |
| 92 | + href="[% Param('mybugstemplate').replace('%userid%', user_login) %]"> |
| 93 | + [% END %] |
| 94 | + |
| 95 | + [% FOREACH q = user.queries %] |
| 96 | + <link rel="Saved Searches" |
| 97 | + title="[% q.name FILTER html %]" |
| 98 | + href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]"> |
| 99 | + [% END %] |
| 100 | + |
| 101 | + [% FOREACH q = user.queries_subscribed %] |
| 102 | + <link rel="Saved Search" |
| 103 | + title="[% q.name FILTER html %] ([% q.user.login FILTER html %])" |
| 104 | + href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd= |
| 105 | + [% q.name FILTER url_quote %]&sharer_id= |
| 106 | + [% q.user.id FILTER url_quote %]"> |
| 107 | + [% END %] |
| 108 | + |
| 109 | + [%# *** Bugzilla Administration Tools *** %] |
| 110 | + [% IF user.login %] |
| 111 | + [% '<link rel="Administration" title="Parameters" |
| 112 | + href="editparams.cgi">' IF user.in_group('tweakparams') %] |
| 113 | + [% '<link rel="Administration" title="Users" |
| 114 | + href="editusers.cgi">' IF user.in_group('editusers') %] |
| 115 | + [% '<link rel="Administration" title="Products" href="editproducts.cgi">' |
| 116 | + IF user.in_group('editcomponents') || user.get_products_by_permission("editcomponents").size %] |
| 117 | + [% '<link rel="Administration" title="Flag Types" |
| 118 | + href="editflagtypes.cgi">' IF user.in_group('editcomponents') %] |
| 119 | + [% '<link rel="Administration" title="Groups" |
| 120 | + href="editgroups.cgi">' IF user.in_group('creategroups') %] |
| 121 | + [% '<link rel="Administration" title="Keywords" |
| 122 | + href="editkeywords.cgi">' IF user.in_group('editkeywords') %] |
| 123 | + [% '<link rel="Administration" title="Whining" |
| 124 | + href="editwhines.cgi">' IF user.in_group('bz_canusewhines') %] |
| 125 | + [% '<link rel="Administration" title="Sanity Check" |
| 126 | + href="sanitycheck.cgi">' IF user.in_group('editcomponents') %] |
| 127 | + [% END %] |
| 128 | +[% END %] |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/site-navigation.html.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 129 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/nav-links.html.tmpl |
— | — | @@ -0,0 +1,10 @@ |
| 2 | + |
| 3 | + <li><a href="query.cgi?format=specific">Search bugs</a></li> |
| 4 | + <li><a href="query.cgi?format=advanced">Advanced search</a></li> |
| 5 | + <li><a href="enter_bug.cgi">Enter a new [% terms.bug %]</a></li> |
| 6 | + [% IF doc_section && Param('docs_urlbase') %] |
| 7 | + <li> |
| 8 | + <a href="[% docs_urlbase _ doc_section FILTER html %]" target="_blank">Help</a> |
| 9 | + </li> |
| 10 | + [% END %] |
| 11 | + |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/nav-links.html.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 12 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/search-links.html.tmpl |
— | — | @@ -0,0 +1,31 @@ |
| 2 | + |
| 3 | +[%# Saved searches %] |
| 4 | + |
| 5 | + [% IF user.showmybugslink %] |
| 6 | + [% filtered_username = user.login FILTER url_quote %] |
| 7 | + <li><a href="[% Param('mybugstemplate').replace('%userid%', filtered_username) %]">My [% terms.Bugs %]</a></li> |
| 8 | + [% END %] |
| 9 | + |
| 10 | + [% FOREACH q = user.queries %] |
| 11 | + [% IF q.link_in_footer %] |
| 12 | + <li> |
| 13 | + <a href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]">[% q.name FILTER html %]</a> |
| 14 | + </li> |
| 15 | + [% END %] |
| 16 | + [% END %] |
| 17 | + [% FOREACH q = user.queries_subscribed %] |
| 18 | + [% IF new_line %] |
| 19 | + <br> |
| 20 | + [% new_line = 0 %] |
| 21 | + [% END %] |
| 22 | + <li> |
| 23 | + <a href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd= |
| 24 | + [% q.name FILTER url_quote %]&sharer_id= |
| 25 | + [% q.user.id FILTER url_quote %]" |
| 26 | + class="shared" |
| 27 | + title="Shared by [% q.user.identity FILTER html %]" |
| 28 | + >[% q.name FILTER html FILTER no_break %] |
| 29 | + </a> |
| 30 | + </li> |
| 31 | + [% END %] |
| 32 | + |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/search-links.html.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 33 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/header.html.tmpl |
— | — | @@ -0,0 +1,145 @@ |
| 2 | +[% IF message %] |
| 3 | + [% PROCESS global/messages.html.tmpl %] |
| 4 | +[% END %] |
| 5 | + |
| 6 | +[% DEFAULT |
| 7 | + subheader = "" |
| 8 | + header_addl_info = "" |
| 9 | + onload = "" |
| 10 | + style_urls = [] |
| 11 | +%] |
| 12 | + |
| 13 | + |
| 14 | +<html> |
| 15 | + <head> |
| 16 | + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
| 17 | + <meta name="generator" content="Buzilla" /> |
| 18 | + <link rel="stylesheet" href="skins/custom/vector.css" media="screen" /> |
| 19 | + |
| 20 | + <meta name="robots" content="index,follow"> |
| 21 | + <title>[% title %]</title> |
| 22 | + |
| 23 | +[%# Migration note: contents of the old Param 'headerhtml' would go here %] |
| 24 | + |
| 25 | + [% PROCESS "global/site-navigation.html.tmpl" %] |
| 26 | + |
| 27 | + [% PROCESS 'global/setting-descs.none.tmpl' %] |
| 28 | + |
| 29 | + [%# Set up the skin CSS cascade: |
| 30 | + # 1. Standard Bugzilla stylesheet set (persistent) |
| 31 | + # 2. Standard Bugzilla stylesheet set (selectable) |
| 32 | + # 3. All third-party "skin" stylesheet sets (selectable) |
| 33 | + # 4. Page-specific styles |
| 34 | + # 5. Custom Bugzilla stylesheet set (persistent) |
| 35 | + # "Selectable" skin file sets may be either preferred or alternate. |
| 36 | + # Exactly one is preferred, determined by the "skin" user preference. |
| 37 | + #%] |
| 38 | + [% IF user.settings.skin.value != 'standard' %] |
| 39 | + [% user_skin = user.settings.skin.value %] |
| 40 | + [% END %] |
| 41 | + [% style_urls.unshift('skins/standard/global.css') %] |
| 42 | + |
| 43 | + |
| 44 | + [%# CSS cascade, part 4: page-specific styles. |
| 45 | + #%] |
| 46 | + [% IF style %] |
| 47 | + <style type="text/css"> |
| 48 | + [% style %] |
| 49 | + </style> |
| 50 | + [% END %] |
| 51 | + |
| 52 | + [%# CSS cascade, part 5: Custom Bugzilla stylesheet set (persistent). |
| 53 | + # Always present. Site administrators may override all other style |
| 54 | + # definitions, including skins, using custom stylesheets. |
| 55 | + #%] |
| 56 | + [% FOREACH style_url = style_urls %] |
| 57 | + [% IF style_url.match('^skins/standard/') %] |
| 58 | + <link href="[% style_url.replace('^skins/standard/', "skins/custom/") |
| 59 | + FILTER html %]" rel="stylesheet" type="text/css"> |
| 60 | + [% END %] |
| 61 | + [% END %] |
| 62 | + <!--[if lte IE 7]> |
| 63 | + [%# Internet Explorer treats [if IE] HTML comments as uncommented. |
| 64 | + # Use it to import CSS fixes so that Bugzilla looks decent on IE 7 |
| 65 | + # and below. |
| 66 | + #%] |
| 67 | + <link href="skins/custom/IE-fixes.css" |
| 68 | + rel="stylesheet" |
| 69 | + type="text/css"> |
| 70 | + <![endif]--> |
| 71 | + |
| 72 | + <script src="js/yui/yahoo-dom-event.js" type="text/javascript"></script> |
| 73 | + <script src="js/global.js" type="text/javascript"></script> |
| 74 | + <script type="text/javascript"> |
| 75 | + <!-- |
| 76 | + YAHOO.namespace('bugzilla'); |
| 77 | + if (YAHOO.env.ua.gecko) { |
| 78 | + YAHOO.util.Event._simpleRemove(window, "unload", |
| 79 | + YAHOO.util.Event._unload); |
| 80 | + } |
| 81 | + [%# Make some Bugzilla information available to all scripts. |
| 82 | + # We don't import every parameter and constant because we |
| 83 | + # don't want to add a lot of uncached JS to every page. |
| 84 | + #%] |
| 85 | + var BUGZILLA = { |
| 86 | + param: { |
| 87 | + cookiepath: '[% Param('cookiepath') FILTER js %]' |
| 88 | + } |
| 89 | + }; |
| 90 | + [% IF javascript %] |
| 91 | + [% javascript %] |
| 92 | + [% END %] |
| 93 | + // --> |
| 94 | + </script> |
| 95 | + |
| 96 | + [% IF javascript_urls %] |
| 97 | + [% FOREACH javascript_url = javascript_urls %] |
| 98 | + <script src="[% javascript_url FILTER html %]" type="text/javascript"></script> |
| 99 | + [% END %] |
| 100 | + [% END %] |
| 101 | + |
| 102 | + [%# this puts the live bookmark up on firefox for the Atom feed %] |
| 103 | + [% IF atomlink %] |
| 104 | + <link rel="alternate" |
| 105 | + type="application/atom+xml" title="Atom feed" |
| 106 | + href="[% atomlink FILTER html %]"> |
| 107 | + [% END %] |
| 108 | + |
| 109 | + [%# Required for the 'Autodiscovery' feature in Firefox 2 and IE 7. %] |
| 110 | + <link rel="search" type="application/opensearchdescription+xml" |
| 111 | + title="[% terms.Bugzilla %]" href="./search_plugin.cgi"> |
| 112 | + <link rel="shortcut icon" href="images/favicon.ico" > |
| 113 | + [% Hook.process("additional_header") %] |
| 114 | + |
| 115 | + </head> |
| 116 | + |
| 117 | +[%# Migration note: contents of the old Param 'bodyhtml' go in the body tag, |
| 118 | + # but set the onload attribute in the DEFAULT directive above. |
| 119 | + #%] |
| 120 | + |
| 121 | + <body class="skin-vector" dir="ltr" onload="[% onload %]" |
| 122 | + class="[% urlbase.replace('^https?://','').replace('/$','').replace('[-~@:/.]+','-') %] |
| 123 | + [% FOREACH class = bodyclasses %] |
| 124 | + [% ' ' %][% class FILTER css_class_quote %] |
| 125 | + [% END %]"> |
| 126 | + |
| 127 | + <div id="page-base" class="noprint"></div> |
| 128 | + <div id="head-base" class="noprint"></div> |
| 129 | + <!-- content --> |
| 130 | + <div id="content-container" > |
| 131 | + <a id="top"></a> |
| 132 | + <!-- bodyContent --> |
| 133 | + <div id="bodyContent"> |
| 134 | + |
| 135 | +[% IF header_addl_info %] |
| 136 | + <p class="header_addl_info">[% header_addl_info %]</p> |
| 137 | + [% END %] |
| 138 | + |
| 139 | + |
| 140 | +[% IF Param('announcehtml') %] |
| 141 | +[% Param('announcehtml') FILTER none %] |
| 142 | +[% END %] |
| 143 | + |
| 144 | +[% IF message %] |
| 145 | +<div id="message">[% message %]</div> |
| 146 | +[% END %] |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/header.html.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 147 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/user-links.html.tmpl |
— | — | @@ -0,0 +1,31 @@ |
| 2 | + <li><a href="report.cgi">Reports</a></li> |
| 3 | + [% IF Param('shutdownhtml') || Bugzilla.has_flags %] |
| 4 | + <li> |
| 5 | + [% IF user.id %] |
| 6 | + <a href="request.cgi?requester=[% user.login FILTER url_quote %]&requestee= |
| 7 | + [% user.login FILTER url_quote %]&do_union=1&group=type&action=queue">My Requests</a> |
| 8 | + [% ELSE %] |
| 9 | + <a href="request.cgi">Requests</a> |
| 10 | + [% END %] |
| 11 | + </li> |
| 12 | + [% END %] |
| 13 | + [% IF user.id && Param('usevotes') %] |
| 14 | + <li><a href="votes.cgi?action=show_user">My Votes</a></li> |
| 15 | + [% END %] |
| 16 | + |
| 17 | + [% IF user.login %] |
| 18 | + <li><a href="userprefs.cgi">Preferences</a></li> |
| 19 | + [% IF user.in_group('tweakparams') || user.in_group('editusers') || user.can_bless |
| 20 | + || (Param('useclassification') && user.in_group('editclassifications')) |
| 21 | + || user.in_group('editcomponents') || user.in_group('admin') || user.in_group('creategroups') |
| 22 | + || user.in_group('editkeywords') || user.in_group('bz_canusewhines') |
| 23 | + || user.get_products_by_permission("editcomponents").size %] |
| 24 | + <li><a href="admin.cgi">Administration</a></li> |
| 25 | + [% END %] |
| 26 | + [% END %] |
| 27 | + |
| 28 | + [% PROCESS "global/per-bug-queries.html.tmpl" %] |
| 29 | + |
| 30 | + [%# Sections of links to more things users can do on this installation. %] |
| 31 | + [% Hook.process("end") %] |
| 32 | + |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/user-links.html.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 33 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/footer.html.tmpl |
— | — | @@ -0,0 +1,126 @@ |
| 2 | +[% PROCESS global/variables.none.tmpl %] |
| 3 | + <div class="visualClear"></div> |
| 4 | + </div> |
| 5 | + <!-- /bodyContent --> |
| 6 | + </div> |
| 7 | + <!-- /content --> |
| 8 | + <!-- header --> |
| 9 | + <div id="head" class="noprint"> |
| 10 | + <!-- /search --> |
| 11 | + <div id="p-search"> |
| 12 | + <h5><label for="searchInput">Search</label></h5> |
| 13 | + <form id="searchform" action="buglist.cgi" method="get" |
| 14 | + onsubmit="if (this.quicksearch.value == '') |
| 15 | + { alert('Please enter one or more search terms first.'); |
| 16 | + return false; } return true;"> |
| 17 | + <input type='hidden' name="title" value="Special:Search"/> |
| 18 | + <div id="simpleSearch"> |
| 19 | + <input id="searchInput" name="quicksearch" type="text" title="Search Bugzilla" value="" /> |
| 20 | + <button id="searchButton" type='submit' name='button' title="Search Bugzilla for this text"> </button> |
| 21 | + </div> |
| 22 | + </form> |
| 23 | + </div> |
| 24 | + <!-- /search --> |
| 25 | + <!-- personal --> |
| 26 | + <div id="p-personal" class=""> |
| 27 | + <h5>Personal tools</h5> |
| 28 | + <ul > |
| 29 | + [% IF user.login %] |
| 30 | + [% IF user.authorizer.can_logout %] |
| 31 | + <li class="user-link"> |
| 32 | + [% IF sudoer %] |
| 33 | + [%+ sudoer.login FILTER html %] (<b>impersonating |
| 34 | + [%+ user.login FILTER html %]</b> |
| 35 | + <a href="relogin.cgi?action=end-sudo">end session</a>) |
| 36 | + [% ELSE %] |
| 37 | + <a href="userprefs.cgi" title="Preferences">[%+ user.login FILTER html %]</a> |
| 38 | + [% END %] |
| 39 | + </li> |
| 40 | + <li><a href="index.cgi?logout=1" title="Log out">Log out</a></li> |
| 41 | + [% ELSE %] |
| 42 | + <li>Logged in as$nbsp;[%+ user.login FILTER html %]</li> |
| 43 | + [% END %] |
| 44 | + [% ELSE %] |
| 45 | + [% IF Param('createemailregexp') |
| 46 | + && user.authorizer.user_can_create_account %] |
| 47 | + <li id="new_account_container[% qs_suffix FILTER html %]"> |
| 48 | + <a href="createaccount.cgi">New Account</a> |
| 49 | + </li> |
| 50 | + [% END %] |
| 51 | + [%# Only display one login form when we're on a LOGIN_REQUIRED page. That |
| 52 | + # way, we're guaranteed that the user will use the form that has |
| 53 | + # hidden_fields in it (the center form) instead of this one. Also, it's |
| 54 | + # less confusing to have one form (as opposed to three) when you're |
| 55 | + # required to log in. |
| 56 | + #%] |
| 57 | + [% IF user.authorizer.can_login && !Bugzilla.page_requires_login %] |
| 58 | + [% PROCESS "account/auth/login-small.html.tmpl" %] |
| 59 | + [% END %] |
| 60 | + |
| 61 | + [% END %] |
| 62 | + </ul> |
| 63 | + </div> |
| 64 | + <!-- /personal --> |
| 65 | + </div> |
| 66 | + <!-- /header --> |
| 67 | + <!-- panel --> |
| 68 | + <div id="panel" class="noprint"> |
| 69 | + <!-- logo --> |
| 70 | + <div id="p-logo"><a style="background-image: url(skins/custom/images/bugzilla-logo.png);" href="./" title="Visit the main page"></a></div> |
| 71 | + <!-- /logo --> |
| 72 | + <!-- navigation --> |
| 73 | + <div class="portal"> |
| 74 | + <h5>Navigation</h5> |
| 75 | + <div class="body"> |
| 76 | + <ul> |
| 77 | + [% PROCESS "global/nav-links.html.tmpl" %] |
| 78 | + </ul> |
| 79 | + </div> |
| 80 | + </div> |
| 81 | + <!-- /navigation --> |
| 82 | + <!-- interaction --> |
| 83 | + [% IF user.showmybugslink OR user.queries.size |
| 84 | + OR user.queries_subscribed.size |
| 85 | + %] |
| 86 | + <div class="portal"> |
| 87 | + <h5>Saved Searches</h5> |
| 88 | + <div class="body"> |
| 89 | + <ul> |
| 90 | + [% PROCESS "global/search-links.html.tmpl" %] |
| 91 | + </ul> |
| 92 | + </div> |
| 93 | + </div> |
| 94 | + [% END %] |
| 95 | + <!-- /interaction --> |
| 96 | + <!-- toolbox --> |
| 97 | + <div class="portal"> |
| 98 | + <h5>Links</h5> |
| 99 | + <div class="body"> |
| 100 | + <ul> |
| 101 | + [% PROCESS "global/user-links.html.tmpl" %] |
| 102 | + </ul> |
| 103 | + </div> |
| 104 | + </div> |
| 105 | + <!-- /toolbox --> |
| 106 | + </div> |
| 107 | + <!-- /panel --> |
| 108 | + |
| 109 | + <!-- footer --> |
| 110 | + <div id="footer" > |
| 111 | + <ul id="footer-info"> |
| 112 | + <li>Bugzilla version [%+ constants.BUGZILLA_VERSION %]</li> |
| 113 | + </ul> |
| 114 | + |
| 115 | + <ul id="footer-places"> |
| 116 | + <li><a href="http://wikimediafoundation.org/wiki/Privacy_policy" title="wikimedia:Privacy policy">Privacy policy</a></li> |
| 117 | + <li><a href="http://www.mediawiki.org/wiki/Project:About" title="Project:About">About MediaWiki.org</a></li> |
| 118 | + <li><a href="http://www.mediawiki.org/wiki/Project:General_disclaimer" title="Project:General disclaimer">Disclaimers</a></li> |
| 119 | + </ul> |
| 120 | + <ul id="footer-icons" class="noprint"> |
| 121 | + <li id="footer-icon-poweredby"><a href="http://www.bugzilla.org/"><img src="skins/custom/images/bugzilla-badge.png" height="31" width="88" alt="Powered by Bugzilla" /></a></li> |
| 122 | + </ul> |
| 123 | + <div style="clear:both"></div> |
| 124 | + </div> |
| 125 | + <!-- /footer --> |
| 126 | + </body> |
| 127 | +</html> |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/global/footer.html.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 128 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/index.html.tmpl |
— | — | @@ -0,0 +1,101 @@ |
| 2 | +[%# 1.0@bugzilla.org %] |
| 3 | +[%# -*- mode: html -*- %] |
| 4 | +[%# The contents of this file are subject to the Mozilla Public |
| 5 | + # License Version 1.1 (the "License"); you may not use this file |
| 6 | + # except in compliance with the License. You may obtain a copy of |
| 7 | + # the License at http://www.mozilla.org/MPL/ |
| 8 | + # |
| 9 | + # Software distributed under the License is distributed on an "AS |
| 10 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 | + # implied. See the License for the specific language governing |
| 12 | + # rights and limitations under the License. |
| 13 | + # |
| 14 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 15 | + # |
| 16 | + # The Initial Developer of the Original Code is Netscape Communications |
| 17 | + # Corporation. Portions created by Netscape are |
| 18 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 19 | + # Rights Reserved. |
| 20 | + # |
| 21 | + # Contributor(s): Terry Weissman <terry@mozilla.org> |
| 22 | + # Jacob Steenhagen <jake@bugzilla.org> |
| 23 | + # Vitaly Harisov <vitaly@rathedg.com> |
| 24 | + #%] |
| 25 | + |
| 26 | +[%# INTERFACE: |
| 27 | + # release: a hash containing data about new releases, if any. |
| 28 | + #%] |
| 29 | + |
| 30 | +[% PROCESS global/variables.none.tmpl %] |
| 31 | + |
| 32 | + |
| 33 | +[% PROCESS global/header.html.tmpl |
| 34 | + title = "$terms.Bugzilla Main Page" |
| 35 | + header = "Main Page" |
| 36 | +%] |
| 37 | + |
| 38 | +<link rel="stylesheet" href="skins/custom/index.css" media="screen" /> |
| 39 | + |
| 40 | +<div id="page-index"> |
| 41 | + <div class="intro"> |
| 42 | + <img src="skins/custom/bugzilla-ayb.png" width="308" height="236" border="2" alt="bugzzz"/> |
| 43 | + </div> |
| 44 | + |
| 45 | + <p>This is the new bug tracker for <a |
| 46 | +href="http://www.mediawiki.org/">MediaWiki</a> and its extensions |
| 47 | +and site-specific problems on <a |
| 48 | +href="http://www.wikimedia.org/">Wikimedia's</a> wiki sites.</p> |
| 49 | + |
| 50 | + <p>Welcome to [% terms.Bugzilla %]. To see what's new in this version |
| 51 | + of [% terms.Bugzilla %], see the |
| 52 | + <a href="page.cgi?id=release-notes.html">release notes</a>! |
| 53 | + You may also want to read the |
| 54 | + <a href="[% Param('docs_urlbase') FILTER html %]using.html"> |
| 55 | + [%- terms.Bugzilla %] User's Guide</a> to find out more about |
| 56 | + [%+ terms.Bugzilla %] and how to use it.</p> |
| 57 | + |
| 58 | + |
| 59 | + <p>For help using this system, please see |
| 60 | + <a |
| 61 | +href="http://www.mediawiki.org/wiki/Bugzilla">Mediawiki:Bugzilla</a>.</p> |
| 62 | + |
| 63 | + <p><b>Not sure how to explain your problem clearly? Read |
| 64 | + <a href="http://www.chiark.greenend.org.uk/~sgtatham/bugs.html"><i>How |
| 65 | +to Report Bugs Effectively</i></a> for some general pointers.</b></p> |
| 66 | + |
| 67 | + <div style="clear:both;"></div> |
| 68 | + <hr /> |
| 69 | + |
| 70 | + <p>But it all boils down to a choice of:</p> |
| 71 | + <ul> |
| 72 | + <li><a href="query.cgi">Search existing [% terms.bug %] reports</a></li> |
| 73 | + <li><a href="enter_bug.cgi">Enter a new [% terms.bug %] report</a></li> |
| 74 | + <li id="report"><a href="report.cgi">Summary reports and charts</a></li> |
| 75 | + <li><a href="javascript:addSidebar()">Add to Sidebar</a> (requires a Mozilla browser like Mozilla Firefox)</li> |
| 76 | + <li id="quick_search_plugin"> |
| 77 | + <a href="javascript:window.external.AddSearchProvider('[% Param('urlbase') %]search_plugin.cgi')">Install |
| 78 | + the Quick Search plugin</a> (requires Firefox 2 or Internet Explorer 7) |
| 79 | + </li> |
| 80 | + |
| 81 | + |
| 82 | + [%# List items of links to more things users can do on this installation. %] |
| 83 | + [% Hook.process("links") %] |
| 84 | + |
| 85 | + </ul> |
| 86 | + |
| 87 | + <form id="f" name="f" action="buglist.cgi" method="get" |
| 88 | + onsubmit="if (this.quicksearch.value == '') |
| 89 | + { alert('Please enter one or more search terms first.'); |
| 90 | + return false; } return true;"> |
| 91 | + <div> |
| 92 | + <p>Enter [% terms.abug %] # or some search terms:</p> |
| 93 | + <input id="quicksearch" type="text" name="quicksearch"> |
| 94 | + <input id="find" type="submit" value="Find"> |
| 95 | + <a href="page.cgi?id=quicksearch.html">[Help]</a> |
| 96 | + </div> |
| 97 | + </form> |
| 98 | + |
| 99 | + <div class="outro"></div> |
| 100 | +</div> |
| 101 | + |
| 102 | +[% PROCESS global/footer.html.tmpl %] |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/index.html.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 103 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/config.json.tmpl |
— | — | @@ -0,0 +1,299 @@ |
| 2 | +[%# The contents of this file are subject to the Mozilla Public |
| 3 | + # License Version 1.1 (the "License"); you may not use this file |
| 4 | + # except in compliance with the License. You may obtain a copy of |
| 5 | + # the License at http://www.mozilla.org/MPL/ |
| 6 | + # |
| 7 | + # Software distributed under the License is distributed on an "AS |
| 8 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + # implied. See the License for the specific language governing |
| 10 | + # rights and limitations under the License. |
| 11 | + # |
| 12 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + # |
| 14 | + # The Initial Developer of the Original Code is Netscape Communications |
| 15 | + # Corporation. Portions created by Netscape are |
| 16 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + # Rights Reserved. |
| 18 | + # |
| 19 | + # Contributor(s): Gervase Markham <gerv@gerv.net> |
| 20 | + #%] |
| 21 | + |
| 22 | +[% |
| 23 | + # Pinched from Bugzilla/API/Model/Utils.pm in BzAPI - need to keep in sync |
| 24 | + OLD2NEW = { |
| 25 | + 'opendate' => 'creation_time', # query |
| 26 | + 'creation_ts' => 'creation_time', |
| 27 | + 'changeddate' => 'last_change_time', # query |
| 28 | + 'delta_ts' => 'last_change_time', |
| 29 | + 'bug_id' => 'id', |
| 30 | + 'rep_platform' => 'platform', |
| 31 | + 'bug_severity' => 'severity', |
| 32 | + 'bug_status' => 'status', |
| 33 | + 'short_desc' => 'summary', |
| 34 | + 'short_short_desc' => 'summary', |
| 35 | + 'bug_file_loc' => 'url', |
| 36 | + 'status_whiteboard' => 'whiteboard', |
| 37 | + 'cclist_accessible' => 'is_cc_accessible', |
| 38 | + 'reporter_accessible' => 'is_reporter_accessible', |
| 39 | + 'everconfirmed' => 'is_everconfirmed', |
| 40 | + 'dependson' => 'depends_on', |
| 41 | + 'blocked' => 'blocks', |
| 42 | + 'attachment' => 'attachments', |
| 43 | + 'flag' => 'flags', |
| 44 | + 'flagtypes.name' => 'flag', |
| 45 | + 'bug_group' => 'group', |
| 46 | + 'group' => 'groups', |
| 47 | + 'longdesc' => 'comment', |
| 48 | + 'bug_file_loc_type' => 'url_type', |
| 49 | + 'bugidtype' => 'id_mode', |
| 50 | + 'longdesc_type' => 'comment_type', |
| 51 | + 'short_desc_type' => 'summary_type', |
| 52 | + 'status_whiteboard_type' => 'whiteboard_type', |
| 53 | + 'emailassigned_to1' => 'email1_assigned_to', |
| 54 | + 'emailassigned_to2' => 'email2_assigned_to', |
| 55 | + 'emailcc1' => 'email1_cc', |
| 56 | + 'emailcc2' => 'email2_cc', |
| 57 | + 'emailqa_contact1' => 'email1_qa_contact', |
| 58 | + 'emailqa_contact2' => 'email2_qa_contact', |
| 59 | + 'emailreporter1' => 'email1_reporter', |
| 60 | + 'emailreporter2' => 'email2_reporter', |
| 61 | + 'emaillongdesc1' => 'email1_comment_author', |
| 62 | + 'emaillongdesc2' => 'email2_comment_author', |
| 63 | + 'emailtype1' => 'email1_type', |
| 64 | + 'emailtype2' => 'email2_type', |
| 65 | + 'chfieldfrom' => 'changed_after', |
| 66 | + 'chfieldto' => 'changed_before', |
| 67 | + 'chfield' => 'changed_field', |
| 68 | + 'chfieldvalue' => 'changed_field_to', |
| 69 | + 'deadlinefrom' => 'deadline_after', |
| 70 | + 'deadlineto' => 'deadline_before', |
| 71 | + 'attach_data.thedata' => 'attachment.data', |
| 72 | + 'longdescs.isprivate' => 'comment.is_private', |
| 73 | + 'commenter' => 'comment.author', |
| 74 | + 'flagtypes.name' => 'flag', |
| 75 | + 'requestees.login_name' => 'flag.requestee', |
| 76 | + 'setters.login_name' => 'flag.setter', |
| 77 | + 'days_elapsed' => 'idle', |
| 78 | + 'owner_idle_time' => 'assignee_idle', |
| 79 | + 'dup_id' => 'dupe_of', |
| 80 | + 'isopened' => 'is_open', |
| 81 | + 'flag_type' => 'flag_types', |
| 82 | + }; |
| 83 | + |
| 84 | + OLDATTACH2NEW = { |
| 85 | + 'submitter' => 'attacher', |
| 86 | + 'description' => 'description', |
| 87 | + 'filename' => 'file_name', |
| 88 | + 'delta_ts' => 'last_change_time', |
| 89 | + 'isurl' => 'is_url', |
| 90 | + 'isobsolete' => 'is_obsolete', |
| 91 | + 'ispatch' => 'is_patch', |
| 92 | + 'isprivate' => 'is_private', |
| 93 | + 'mimetype' => 'content_type', |
| 94 | + 'contenttypeentry' => 'content_type', |
| 95 | + 'date' => 'creation_time', |
| 96 | + 'attachid' => 'id', |
| 97 | + 'desc' => 'description', |
| 98 | + 'flag' => 'flags', |
| 99 | + 'type' => 'content_type' |
| 100 | + }; |
| 101 | +%] |
| 102 | + |
| 103 | +[%# Add attachment stuff to the main hash - but with right prefix. (This is |
| 104 | + # the way the code is structured in BzAPI, and changing it makes it harder |
| 105 | + # to keep the two in sync.) |
| 106 | + #%] |
| 107 | +[% FOREACH entry IN OLDATTACH2NEW %] |
| 108 | + [% newkey = 'attachments.' _ entry.key %] |
| 109 | + [% OLD2NEW.${newkey} = 'attachment.' _ OLDATTACH2NEW.${entry.key} %] |
| 110 | +[% END %] |
| 111 | + |
| 112 | +[% all_visible_flag_types = {} %] |
| 113 | + |
| 114 | +{ |
| 115 | + "version": "[% constants.BUGZILLA_VERSION FILTER json %]", |
| 116 | + "maintainer": "[% Param('maintainer') FILTER json %]", |
| 117 | + "announcement": "[% Param('announcehtml') FILTER json %]", |
| 118 | + "max_attachment_size": "[% (Param('maxattachmentsize') * 1000) FILTER json %]", |
| 119 | + |
| 120 | +[% IF Param('useclassification') %] |
| 121 | + [% classifications = user.get_selectable_classifications() %] |
| 122 | + [% cl_name_for = {} %] |
| 123 | + "classification": { |
| 124 | + [% FOREACH cl IN classifications %] |
| 125 | + [% cl_name_for.${cl.id} = cl.name %] |
| 126 | + "[% cl.name FILTER json %]": { |
| 127 | + "id": [% cl.id %], |
| 128 | + "products": [ |
| 129 | + [% FOREACH product IN cl.products %] |
| 130 | + "[% product.name FILTER json %]"[% ',' UNLESS loop.last() %] |
| 131 | + [% END %] |
| 132 | + ] |
| 133 | + }[% ',' UNLESS loop.last() %] |
| 134 | + [% END %] |
| 135 | + }, |
| 136 | +[% END %] |
| 137 | + |
| 138 | + "product": { |
| 139 | + [% FOREACH product = products %] |
| 140 | + "[% product.name FILTER json %]": { |
| 141 | + "id": [% product.id %], |
| 142 | +[% IF Param('useclassification') %] |
| 143 | + "classification": "[% cl_name_for.${product.classification_id} FILTER json %]", |
| 144 | +[% END %] |
| 145 | + "component": { |
| 146 | + [% FOREACH component = product.components %] |
| 147 | + "[% component.name FILTER json %]": { |
| 148 | + "id": [% component.id %], |
| 149 | + "flag_type": [ |
| 150 | + [% flag_types = |
| 151 | + component.flag_types.bug.merge(component.flag_types.attachment) %] |
| 152 | + [%-# "first" flag used to get commas right; can't use loop.last() in case |
| 153 | + # last flag is inactive %] |
| 154 | + [% first = 1 %] |
| 155 | + [% FOREACH flag_type = flag_types %] |
| 156 | + [% NEXT UNLESS flag_type.is_active %] |
| 157 | + [% all_visible_flag_types.${flag_type.id} = flag_type %] |
| 158 | + [% ',' UNLESS first %][% flag_type.id FILTER json %][% first = 0 %] |
| 159 | + [% END %]] |
| 160 | + } [% ',' UNLESS loop.last() %] |
| 161 | + [% END %] |
| 162 | + }, |
| 163 | + "version": [ |
| 164 | + [% FOREACH version = product.versions %] |
| 165 | + "[% version.name FILTER json %]"[% ',' UNLESS loop.last() %] |
| 166 | + [% END %] |
| 167 | + ], |
| 168 | + |
| 169 | +[% IF Param('usetargetmilestone') %] |
| 170 | + "target_milestone": [ |
| 171 | + [% FOREACH milestone = product.milestones %] |
| 172 | + "[% milestone.name FILTER json %]"[% ',' UNLESS loop.last() %] |
| 173 | + [% END %] |
| 174 | + ], |
| 175 | +[% END %] |
| 176 | + |
| 177 | + "group": [ |
| 178 | + [% FOREACH group = product.groups_valid %] |
| 179 | + [% group.id %][% ',' UNLESS loop.last() %] |
| 180 | + [% END %] |
| 181 | + ] |
| 182 | + }[% ',' UNLESS loop.last() %] |
| 183 | + [% END %] |
| 184 | + }, |
| 185 | + |
| 186 | + "group": { |
| 187 | + [% FOREACH group = product.groups_valid %] |
| 188 | + "[% group.id %]": { |
| 189 | + "name": "[% group.name FILTER json %]", |
| 190 | + "description": "[% group.description FILTER json %]", |
| 191 | + "is_accepting_bugs": [% group.is_bug_group %], |
| 192 | + "is_active": [% group.is_active %] |
| 193 | + }[% ',' UNLESS loop.last() %] |
| 194 | + [% END %] |
| 195 | + }, |
| 196 | + |
| 197 | + "flag_type": { |
| 198 | + [% FOREACH flag_type = all_visible_flag_types.values.sort('name') %] |
| 199 | + "[%+ flag_type.id %]": { |
| 200 | + "name": "[% flag_type.name FILTER json %]", |
| 201 | + "description": "[% flag_type.description FILTER json %]", |
| 202 | + [% IF user.in_group("editcomponents") %] |
| 203 | + "request_group": [% flag_type.request_group.id %], |
| 204 | + "grant_group": [% flag_type.grant_group.id %], |
| 205 | + [% END %] |
| 206 | + "is_for_bugs": [% flag_type.target_type == "bug" ? 1 : 0 %], |
| 207 | + "is_requestable": [% flag_type.is_requestable %], |
| 208 | + "is_specifically_requestable": [% flag_type.is_requesteeble %], |
| 209 | + "is_multiplicable": [% flag_type.is_multiplicable %] |
| 210 | + }[% ',' UNLESS loop.last() %] |
| 211 | + [% END %] |
| 212 | + }, |
| 213 | + |
| 214 | + [% PROCESS "global/field-descs.none.tmpl" %] |
| 215 | + |
| 216 | + [%# Put custom field value data where below loop expects to find it %] |
| 217 | + [% FOREACH cf = custom_fields %] |
| 218 | + [% ${cf.name} = [] %] |
| 219 | + [% FOREACH value = cf.legal_values %] |
| 220 | + [% ${cf.name}.push(value.name) %] |
| 221 | + [% END %] |
| 222 | + [% END %] |
| 223 | + |
| 224 | + [%# Built-in fields do not have type IDs. There aren't ID values for all |
| 225 | + # the types of the built-in fields, but we do what we can, and leave the |
| 226 | + # rest as "0" (unknown). |
| 227 | + #%] |
| 228 | + [% type_id_for = { |
| 229 | + "id" => 6, |
| 230 | + "summary" => 1, |
| 231 | + "classification" => 2, |
| 232 | + "version" => 2, |
| 233 | + "url" => 1, |
| 234 | + "whiteboard" => 1, |
| 235 | + "keywords" => 3, |
| 236 | + "component" => 2, |
| 237 | + "attachment.description" => 1, |
| 238 | + "attachment.file_name" => 1, |
| 239 | + "attachment.content_type" => 1, |
| 240 | + "target_milestone" => 2, |
| 241 | + "comment" => 4, |
| 242 | + "alias" => 1, |
| 243 | + "deadline" => 5, |
| 244 | + } %] |
| 245 | + |
| 246 | + "field": { |
| 247 | + [% FOREACH item = field %] |
| 248 | + [% newname = OLD2NEW.${item.name} || item.name %] |
| 249 | + "[% newname FILTER json %]": { |
| 250 | + "description": "[% (field_descs.${item.name} OR |
| 251 | + item.description) FILTER json %]", |
| 252 | + [% blacklist = ["version", "group", "product", "component"] %] |
| 253 | + [% IF ${newname} AND NOT blacklist.contains(newname) %] |
| 254 | + "values": [ |
| 255 | + [% FOREACH value = ${newname} %] |
| 256 | + "[% value FILTER json %]"[% ',' UNLESS loop.last() %] |
| 257 | + [% END %] |
| 258 | + ], |
| 259 | + [% END %] |
| 260 | + [% paramname = newname.replace("_", "") %] [%# For op_sys... %] |
| 261 | + [% IF Param('default' _ paramname) %] |
| 262 | + "default": "[% Param('default' _ paramname) %]", |
| 263 | + [% END %] |
| 264 | + [%-# The 'status' hash has a lot of extra stuff %] |
| 265 | + [% IF newname == "status" %] |
| 266 | + "open": [ |
| 267 | + [% FOREACH value = open_status %] |
| 268 | + "[% value FILTER json %]"[% ',' UNLESS loop.last() %] |
| 269 | + [% END %] |
| 270 | + ], |
| 271 | + "closed": [ |
| 272 | + [% FOREACH value = closed_status %] |
| 273 | + "[% value FILTER json %]"[% ',' UNLESS loop.last() %] |
| 274 | + [% END %] |
| 275 | + ], |
| 276 | + "transitions": { |
| 277 | + "{Start}": [ |
| 278 | + [% FOREACH target = initial_status %] |
| 279 | + "[% target.name %]"[% ',' UNLESS loop.last() %] |
| 280 | + [% END %] |
| 281 | + ], |
| 282 | + [% FOREACH status = status_objects %] |
| 283 | + [% targets = status.can_change_to() %] |
| 284 | + "[% status.name FILTER json %]": [ |
| 285 | + [% FOREACH target = targets %] |
| 286 | + "[% target.name %]"[% ',' UNLESS loop.last() %] |
| 287 | + [% END %] |
| 288 | + ][% ',' UNLESS loop.last() %] |
| 289 | + [% END %] |
| 290 | + }, |
| 291 | + [% END %] |
| 292 | + [% IF newname.match("^cf_") %] |
| 293 | + "is_on_bug_entry": [% item.enter_bug %], |
| 294 | + [% END %] |
| 295 | + "type": [% item.type || type_id_for.$newname || 0 %] |
| 296 | + }[% ',' UNLESS loop.last() %] |
| 297 | + [% END %] |
| 298 | + } |
| 299 | +} |
| 300 | + |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/config.json.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 301 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/account/auth/login-small.html.tmpl |
— | — | @@ -0,0 +1,119 @@ |
| 2 | +[%# The contents of this file are subject to the Mozilla Public |
| 3 | + # License Version 1.1 (the "License"); you may not use this file |
| 4 | + # except in compliance with the License. You may obtain a copy of |
| 5 | + # the License at http://www.mozilla.org/MPL/ |
| 6 | + # |
| 7 | + # Software distributed under the License is distributed on an "AS |
| 8 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + # implied. See the License for the specific language governing |
| 10 | + # rights and limitations under the License. |
| 11 | + # |
| 12 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + # |
| 14 | + # The Initial Developer of the Original Code is Netscape Communications |
| 15 | + # Corporation. Portions created by Netscape are |
| 16 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + # Rights Reserved. |
| 18 | + # |
| 19 | + # Contributor(s): Jacob Steenhagen <jake@bugzilla.org> |
| 20 | + #%] |
| 21 | + |
| 22 | +[% PROCESS global/variables.none.tmpl %] |
| 23 | + |
| 24 | +[%# Use the current script name. If an empty name is returned, |
| 25 | + # then we are accessing the home page. %] |
| 26 | + |
| 27 | +[% login_target = cgi.url("-relative" => 1, "-query" => 1) %] |
| 28 | +[% IF !login_target || login_target.match('^token.cgi') %] |
| 29 | + [% login_target = "index.cgi" %] |
| 30 | +[% END %] |
| 31 | + |
| 32 | +[%# If SSL is in use, use 'sslbase', else use 'urlbase'. %] |
| 33 | +[% IF Param("sslbase") != "" && Param("ssl") != "never" %] |
| 34 | + [% login_target = Param("sslbase") _ login_target %] |
| 35 | +[% ELSE %] |
| 36 | + [% login_target = Param("urlbase") _ login_target %] |
| 37 | +[% END %] |
| 38 | + |
| 39 | +<li id="mini_login_container[% qs_suffix %]"> |
| 40 | + <a id="login_link[% qs_suffix %]" href="?GoAheadAndLogIn=1" |
| 41 | + onclick="return show_mini_login_form('[% qs_suffix %]')">Log In</a> |
| 42 | + <form action="[% login_target FILTER html %]" method="POST" |
| 43 | + class="mini_login bz_default_hidden" |
| 44 | + id="mini_login[% qs_suffix FILTER html %]" |
| 45 | + onsubmit="return check_mini_login_fields( '[% qs_suffix FILTER html %]' );" |
| 46 | + > |
| 47 | + <input id="Bugzilla_login[% qs_suffix FILTER html %]" |
| 48 | + class="bz_login" |
| 49 | + name="Bugzilla_login" |
| 50 | + onfocus="mini_login_on_focus('[% qs_suffix FILTER js %]')" |
| 51 | + > |
| 52 | + <input class="bz_password" |
| 53 | + id="Bugzilla_password[% qs_suffix FILTER html %]" |
| 54 | + name="Bugzilla_password" |
| 55 | + type="password" |
| 56 | + > |
| 57 | + <input class="bz_password bz_default_hidden bz_mini_login_help" type="text" |
| 58 | + id="Bugzilla_password_dummy[% qs_suffix %]" value="password" |
| 59 | + onfocus="mini_login_on_focus('[% qs_suffix FILTER js %]')" |
| 60 | + > |
| 61 | + [% IF Param('rememberlogin') == 'defaulton' || |
| 62 | + Param('rememberlogin') == 'defaultoff' |
| 63 | + %] |
| 64 | + <input type="checkbox" id="Bugzilla_remember[% qs_suffix %]" |
| 65 | + name="Bugzilla_remember" value="on" class="bz_remember" |
| 66 | + [%+ "checked" IF Param('rememberlogin') == "defaulton" %]> |
| 67 | + <label for="Bugzilla_remember[% qs_suffix %]">Remember</label> |
| 68 | + [% END %] |
| 69 | + <input type="submit" name="GoAheadAndLogIn" value="Log in" |
| 70 | + id="log_in[% qs_suffix %]"> |
| 71 | + <script type="text/javascript"> |
| 72 | + mini_login_constants = { |
| 73 | + "login" : "login", |
| 74 | + "warning" : "You must set the login and password before logging in." |
| 75 | + }; |
| 76 | + [%# We need this event to fire after autocomplete, because it does |
| 77 | + # something different depending on whether or not there's already |
| 78 | + # data in the login and password box. |
| 79 | + # However, autocomplete happens at all sorts of different times in |
| 80 | + # different browsers (before or after onDOMReady, before or after |
| 81 | + # window.onload, in almost all combinations you can imagine). |
| 82 | + # The only good solution I found is to time the event 200 |
| 83 | + # milliseconds after window.onload for WebKit (doing it immediately |
| 84 | + # at onload works in Chrome but not in Safari, but I can't detect |
| 85 | + # them separately using YUI), and right after onDOMReady in Gecko. |
| 86 | + # The WebKit solution is also fairly guaranteed to work on any |
| 87 | + # browser (it's just strange, since the fields only populate 200 ms |
| 88 | + # after the page loads), so it's the default. IE doesn't even |
| 89 | + # recognize our forms as login forms, so I made it use the Gecko |
| 90 | + # method also (since it's nicer visually). Opera never autocompletes |
| 91 | + # forms without user interaction, so it also uses the Gecko method. |
| 92 | + #%] |
| 93 | + if (YAHOO.env.ua.gecko || YAHOO.env.ua.ie || YAHOO.env.ua.opera) { |
| 94 | + YAHOO.util.Event.onDOMReady(function() { |
| 95 | + init_mini_login_form('[% qs_suffix FILTER html %]'); |
| 96 | + }); |
| 97 | + } |
| 98 | + else { |
| 99 | + YAHOO.util.Event.on(window, 'load', function () { |
| 100 | + window.setTimeout(function() { |
| 101 | + init_mini_login_form('[% qs_suffix FILTER html %]'); |
| 102 | + }, 200); |
| 103 | + }); |
| 104 | + } |
| 105 | + </script> |
| 106 | + <a href="#" onclick="return hide_mini_login_form('[% qs_suffix %]')">[x]</a> |
| 107 | + </form> |
| 108 | +</li> |
| 109 | +<li id="forgot_container[% qs_suffix %]"> |
| 110 | + <a id="forgot_link[% qs_suffix %]" href="?GoAheadAndLogIn=1#forgot" |
| 111 | + onclick="return show_forgot_form('[% qs_suffix %]')">Forgot Password</a> |
| 112 | + <form action="token.cgi" method="post" id="forgot_form[% qs_suffix %]" |
| 113 | + class="mini_forgot bz_default_hidden"> |
| 114 | + <label>Login: <input type="text" name="loginname" size="20"></label> |
| 115 | + <input id="forgot_button[% qs_suffix %]" value="Reset Password" |
| 116 | + type="submit"> |
| 117 | + <input type="hidden" name="a" value="reqpw"> |
| 118 | + <a href="#" onclick="return hide_forgot_form('[% qs_suffix %]')">[x]</a> |
| 119 | + </form> |
| 120 | +</li> |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/account/auth/login-small.html.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 121 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/bug/edit.html.tmpl |
— | — | @@ -0,0 +1,1179 @@ |
| 2 | +[%# |
| 3 | + # The only customizations to the table are the order of the various blocks. |
| 4 | + # Content of the blocks has not been changed -pdhanda |
| 5 | + #%] |
| 6 | + |
| 7 | +[%# The contents of this file are subject to the Mozilla Public |
| 8 | + # License Version 1.1 (the "License"); you may not use this file |
| 9 | + # except in compliance with the License. You may obtain a copy of |
| 10 | + # the License at http://www.mozilla.org/MPL/ |
| 11 | + # |
| 12 | + # Software distributed under the License is distributed on an "AS |
| 13 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 14 | + # implied. See the License for the specific language governing |
| 15 | + # rights and limitations under the License. |
| 16 | + # |
| 17 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 18 | + # |
| 19 | + # The Initial Developer of the Original Code is Netscape Communications |
| 20 | + # Corporation. Portions created by Netscape are |
| 21 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 22 | + # Rights Reserved. |
| 23 | + # |
| 24 | + # Contributor(s): Gervase Markham <gerv@gerv.net> |
| 25 | + # Vaskin Kissoyan <vkissoyan@yahoo.com> |
| 26 | + # Max Kanat-Alexander <mkanat@bugzilla.org> |
| 27 | + # Frédéric Buclin <LpSolit@gmail.com> |
| 28 | + # Olav Vitters <olav@bkor.dhs.org> |
| 29 | + # Guy Pyrzak <guy.pyrzak@gmail.com> |
| 30 | + # Elliotte Martin <emartin@everythingsolved.com> |
| 31 | + #%] |
| 32 | + |
| 33 | +[% PROCESS global/variables.none.tmpl %] |
| 34 | + |
| 35 | +[% PROCESS "global/field-descs.none.tmpl" %] |
| 36 | + |
| 37 | +[% PROCESS bug/time.html.tmpl %] |
| 38 | + |
| 39 | +[% USE Bugzilla %] |
| 40 | +[% SET select_fields = {} %] |
| 41 | +[% FOREACH field = Bugzilla.get_fields( |
| 42 | + { type => constants.FIELD_TYPE_SINGLE_SELECT, custom => 0 }) |
| 43 | +%] |
| 44 | + [% select_fields.${field.name} = field %] |
| 45 | +[% END %] |
| 46 | + |
| 47 | + <script type="text/javascript"> |
| 48 | + <!-- |
| 49 | + |
| 50 | + /* Outputs a link to call replyToComment(); used to reduce HTML output */ |
| 51 | + function addReplyLink(id, real_id) { |
| 52 | + /* XXX this should really be updated to use the DOM Core's |
| 53 | + * createElement, but finding a container isn't trivial. |
| 54 | + */ |
| 55 | + [% IF user.settings.quote_replies.value != 'off' %] |
| 56 | + document.write('[<a href="#add_comment" onclick="replyToComment(' + |
| 57 | + id + ',' + real_id + ');">reply<' + '/a>]'); |
| 58 | + [% END %] |
| 59 | + } |
| 60 | + |
| 61 | + /* Adds the reply text to the `comment' textarea */ |
| 62 | + function replyToComment(id, real_id) { |
| 63 | + var prefix = "(In reply to comment #" + id + ")\n"; |
| 64 | + var replytext = ""; |
| 65 | + [% IF user.settings.quote_replies.value == 'quoted_reply' %] |
| 66 | + /* pre id="comment_name_N" */ |
| 67 | + var text_elem = document.getElementById('comment_text_'+id); |
| 68 | + var text = getText(text_elem); |
| 69 | + |
| 70 | + /* make sure we split on all newlines -- IE or Moz use \r and \n |
| 71 | + * respectively. |
| 72 | + */ |
| 73 | + text = text.split(/\r|\n/); |
| 74 | + |
| 75 | + for (var i=0; i < text.length; i++) { |
| 76 | + replytext += "> " + text[i] + "\n"; |
| 77 | + } |
| 78 | + |
| 79 | + replytext = prefix + replytext + "\n"; |
| 80 | + [% ELSIF user.settings.quote_replies.value == 'simple_reply' %] |
| 81 | + replytext = prefix; |
| 82 | + [% END %] |
| 83 | + |
| 84 | + [% IF Param("insidergroup") && user.in_group(Param("insidergroup")) %] |
| 85 | + if (document.getElementById('isprivate_' + real_id).checked) { |
| 86 | + document.getElementById('newcommentprivacy').checked = 'checked'; |
| 87 | + } |
| 88 | + [% END %] |
| 89 | + |
| 90 | + /* <textarea id="comment"> */ |
| 91 | + var textarea = document.getElementById('comment'); |
| 92 | + textarea.value += replytext; |
| 93 | + |
| 94 | + textarea.focus(); |
| 95 | + } |
| 96 | + |
| 97 | + if (typeof Node == 'undefined') { |
| 98 | + /* MSIE doesn't define Node, so provide a compatibility object */ |
| 99 | + window.Node = { |
| 100 | + TEXT_NODE: 3, |
| 101 | + ENTITY_REFERENCE_NODE: 5 |
| 102 | + }; |
| 103 | + } |
| 104 | + |
| 105 | + /* Concatenates all text from element's childNodes. This is used |
| 106 | + * instead of innerHTML because we want the actual text (and |
| 107 | + * innerText is non-standard). |
| 108 | + */ |
| 109 | + function getText(element) { |
| 110 | + var child, text = ""; |
| 111 | + for (var i=0; i < element.childNodes.length; i++) { |
| 112 | + child = element.childNodes[i]; |
| 113 | + var type = child.nodeType; |
| 114 | + if (type == Node.TEXT_NODE || type == Node.ENTITY_REFERENCE_NODE) { |
| 115 | + text += child.nodeValue; |
| 116 | + } else { |
| 117 | + /* recurse into nodes of other types */ |
| 118 | + text += getText(child); |
| 119 | + } |
| 120 | + } |
| 121 | + return text; |
| 122 | + } |
| 123 | + |
| 124 | +[% IF user.in_group(Param('timetrackinggroup')) %] |
| 125 | + var fRemainingTime = [% bug.remaining_time %]; // holds the original value |
| 126 | + function adjustRemainingTime() { |
| 127 | + // subtracts time spent from remaining time |
| 128 | + var new_time; |
| 129 | + |
| 130 | + // prevent negative values if work_time > fRemainingTime |
| 131 | + new_time = |
| 132 | + Math.max(fRemainingTime - document.changeform.work_time.value, 0.0); |
| 133 | + // get upto 2 decimal places |
| 134 | + document.changeform.remaining_time.value = |
| 135 | + Math.round(new_time * 100)/100; |
| 136 | + } |
| 137 | + |
| 138 | + function updateRemainingTime() { |
| 139 | + // if the remaining time is changed manually, update fRemainingTime |
| 140 | + fRemainingTime = document.changeform.remaining_time.value; |
| 141 | + } |
| 142 | + |
| 143 | +[% END %] |
| 144 | + |
| 145 | + //--> |
| 146 | + </script> |
| 147 | + |
| 148 | +<form name="changeform" method="post" action="process_bug.cgi"> |
| 149 | + |
| 150 | + <input type="hidden" name="delta_ts" value="[% bug.delta_ts %]"> |
| 151 | + <input type="hidden" name="longdesclength" value="[% bug.longdescs.size %]"> |
| 152 | + <input type="hidden" name="id" value="[% bug.bug_id %]"> |
| 153 | + <input type="hidden" name="token" value="[% issue_hash_token([bug.id, bug.delta_ts]) FILTER html %]"> |
| 154 | + |
| 155 | + [% PROCESS section_title %] |
| 156 | + <table class="edit_form"> |
| 157 | + <tr> |
| 158 | + [%# 1st Column %] |
| 159 | + <td id="bz_show_bug_column_1" class="bz_show_bug_column"> |
| 160 | + <table> |
| 161 | + [%# *** ID, product, component, status, resolution, Hardware, and OS *** %] |
| 162 | + [% PROCESS section_status %] |
| 163 | + |
| 164 | + [% PROCESS section_spacer %] |
| 165 | + |
| 166 | + [% PROCESS section_details1 %] |
| 167 | + |
| 168 | + [% PROCESS section_spacer %] |
| 169 | + |
| 170 | + [%# *** severity, priority, version and milestone *** %] |
| 171 | + [% PROCESS section_details2 %] |
| 172 | + |
| 173 | + [%# *** assigned to and qa contact *** %] |
| 174 | + [% PROCESS section_people %] |
| 175 | + |
| 176 | + [% PROCESS section_spacer %] |
| 177 | + |
| 178 | + [% PROCESS section_url_keyword_whiteboard %] |
| 179 | + |
| 180 | + [% PROCESS section_spacer %] |
| 181 | + |
| 182 | + [%# *** Dependencies *** %] |
| 183 | + [% PROCESS section_dependson_blocks %] |
| 184 | + |
| 185 | + </table> |
| 186 | + </td> |
| 187 | + <td> |
| 188 | + <div class="bz_column_spacer"> </div> |
| 189 | + </td> |
| 190 | + [%# 2nd Column %] |
| 191 | + <td id="bz_show_bug_column_2" class="bz_show_bug_column"> |
| 192 | + <table cellpadding="3" cellspacing="1"> |
| 193 | + [%# *** Reported and modified dates *** %] |
| 194 | + [% PROCESS section_dates %] |
| 195 | + |
| 196 | + [% PROCESS section_cclist %] |
| 197 | + |
| 198 | + [% PROCESS section_spacer %] |
| 199 | + |
| 200 | + [% PROCESS section_see_also %] |
| 201 | + |
| 202 | + [% PROCESS section_customfields %] |
| 203 | + |
| 204 | + [% PROCESS section_spacer %] |
| 205 | + |
| 206 | + [% Hook.process("after_custom_fields") %] |
| 207 | + |
| 208 | + [% PROCESS section_flags %] |
| 209 | + |
| 210 | + </table> |
| 211 | + </td> |
| 212 | + </tr> |
| 213 | + <tr> |
| 214 | + <td colspan="3"> |
| 215 | + <hr id="bz_top_half_spacer"> |
| 216 | + </td> |
| 217 | + </tr> |
| 218 | + </table> |
| 219 | + |
| 220 | + |
| 221 | + [% PROCESS section_restrict_visibility %] |
| 222 | + |
| 223 | +[%# *** Attachments *** %] |
| 224 | + |
| 225 | + [% PROCESS attachment/list.html.tmpl |
| 226 | + attachments = bug.attachments |
| 227 | + bugid = bug.bug_id |
| 228 | + num_attachment_flag_types = bug.num_attachment_flag_types |
| 229 | + show_attachment_flags = bug.show_attachment_flags |
| 230 | + %] |
| 231 | + |
| 232 | + |
| 233 | +[%# *** Comments Groups *** %] |
| 234 | + |
| 235 | + <table cellpadding="1" cellspacing="1"> |
| 236 | + <tr> |
| 237 | + <td id="comment_status_commit"> |
| 238 | + <!-- The table keeps the commit button aligned with the box. --> |
| 239 | + <hr> |
| 240 | + <div id="comments"> |
| 241 | + [% PROCESS bug/comments.html.tmpl |
| 242 | + comments = bug.longdescs |
| 243 | + mode = user.id ? "edit" : "show" |
| 244 | + %] |
| 245 | + </div> |
| 246 | + <a name="add_comment"></a> |
| 247 | + [% IF user.id %] |
| 248 | + <table><tr><td> |
| 249 | + <label for="comment" accesskey="c"><b>Additional <u>C</u>omments</b></label>: |
| 250 | + [% IF Param("insidergroup") && user.in_group(Param("insidergroup")) %] |
| 251 | + <input type="checkbox" name="commentprivacy" value="1" |
| 252 | + id="newcommentprivacy" |
| 253 | + onClick="updateCommentTagControl(this, form)"> |
| 254 | + <label for="newcommentprivacy">Private</label> |
| 255 | + [% END %] |
| 256 | + <br> |
| 257 | + [% INCLUDE global/textarea.html.tmpl |
| 258 | + name = 'comment' |
| 259 | + id = 'comment' |
| 260 | + minrows = 10 |
| 261 | + maxrows = 25 |
| 262 | + cols = constants.COMMENT_COLS |
| 263 | + %] |
| 264 | + [% Hook.process("after_comment_textarea") %] |
| 265 | + <br> |
| 266 | + [% PROCESS commit_button id=""%] |
| 267 | + <table class="status" cellspacing="0" cellpadding="0"> |
| 268 | + <tr> |
| 269 | + <td class="field_label"> |
| 270 | + <b><a href="page.cgi?id=fields.html#status">Status</a></b>: |
| 271 | + </td> |
| 272 | + <td> |
| 273 | + <a name="bug_status_bottom"></a> |
| 274 | + [% PROCESS bug/knob.html.tmpl %] |
| 275 | + </td> |
| 276 | + </tr> |
| 277 | + </table> |
| 278 | + </td></tr></table> |
| 279 | + [% ELSE %] |
| 280 | + <fieldset> |
| 281 | + <legend>Note</legend> |
| 282 | + <p> |
| 283 | + You need to |
| 284 | + <a href="[% IF Param('ssl') != 'never' %][% Param('sslbase') %][% END %]show_bug.cgi?id=[% bug.bug_id %]&GoAheadAndLogIn=1">log in</a> |
| 285 | + before you can comment on or make changes to this [% terms.bug %]. |
| 286 | + </p> |
| 287 | + </fieldset> |
| 288 | + [% END %] |
| 289 | + [%# *** Additional Comments *** %] |
| 290 | + |
| 291 | + </td> |
| 292 | + </tr> |
| 293 | + </table> |
| 294 | + |
| 295 | + [% IF user.in_group(Param('timetrackinggroup')) %] |
| 296 | + <br> |
| 297 | + [% PROCESS section_timetracking %] |
| 298 | + [% END %] |
| 299 | + |
| 300 | +</form> |
| 301 | + |
| 302 | +[%############################################################################%] |
| 303 | +[%# Block for the Title (alias and short desc) #%] |
| 304 | +[%############################################################################%] |
| 305 | + |
| 306 | +[% BLOCK section_title %] |
| 307 | + [%# That's the main table, which contains all editable fields. %] |
| 308 | + <div class="bz_alias_short_desc_container edit_form"> |
| 309 | + [% PROCESS commit_button id="_top"%] |
| 310 | + <a href="show_bug.cgi?id=[% bug.bug_id %]"> |
| 311 | + <b>[% terms.Bug %] [% bug.bug_id FILTER html %]</b></a> - |
| 312 | + <span id="summary_alias_container" class="bz_default_hidden"> |
| 313 | + [% IF Param("usebugaliases") %] |
| 314 | + [% IF bug.alias != "" %] |
| 315 | + (<span id="alias_nonedit_display">[% bug.alias FILTER html %]</span>) |
| 316 | + [% END %] |
| 317 | + [% END %] |
| 318 | + <span id="short_desc_nonedit_display">[% bug.short_desc FILTER html %]</span> |
| 319 | + [% IF bug.check_can_change_field('short_desc', 0, 1) || |
| 320 | + bug.check_can_change_field('alias', 0, 1) %] |
| 321 | + <small class="editme">(<a href="#" id="editme_action">edit</a>)</small> |
| 322 | + [% END %] |
| 323 | + </span> |
| 324 | + |
| 325 | + |
| 326 | + <div id="summary_alias_input"> |
| 327 | + <table id="summary"> |
| 328 | + [% IF Param("usebugaliases") %] |
| 329 | + <tr> |
| 330 | + [% IF bug.check_can_change_field('alias', 0, 1) %] |
| 331 | + <td> |
| 332 | + <label |
| 333 | + for="alias" |
| 334 | + title="a name for the |
| 335 | + [% terms.bug %] that can be used in place of its ID number, |
| 336 | + [%%] e.g. when adding it to a list of dependencies" |
| 337 | + >Alias</label>:</td><td> |
| 338 | + [% ELSIF bug.alias %] |
| 339 | + <td colspan="2">( |
| 340 | + [% ELSE %] |
| 341 | + <td colspan="2"> |
| 342 | + [% END %] |
| 343 | + [% PROCESS input inputname => "alias" |
| 344 | + size => "20" |
| 345 | + maxlength => "20" |
| 346 | + no_td => 1 |
| 347 | + %][% ")" IF NOT bug.check_can_change_field('alias', 0, 1) |
| 348 | + && bug.alias %] |
| 349 | + </td> |
| 350 | + </tr> |
| 351 | + [% END %] |
| 352 | + [%# *** Summary *** %] |
| 353 | + <tr> |
| 354 | + <td> |
| 355 | + <label accesskey="s" for="short_desc"><u>S</u>ummary</label>: |
| 356 | + </td> |
| 357 | + <td> |
| 358 | + [% PROCESS input inputname => "short_desc" size => "80" colspan => 2 |
| 359 | + maxlength => 255 spellcheck => "true" no_td => 1 %] |
| 360 | + </td> |
| 361 | + </tr> |
| 362 | + </table> |
| 363 | + </div> |
| 364 | + </div> |
| 365 | + <script type="text/javascript"> |
| 366 | + hideAliasAndSummary('[% bug.short_desc FILTER js %]', '[% bug.alias FILTER js %]'); |
| 367 | + </script> |
| 368 | +[% END %] |
| 369 | + |
| 370 | +[%############################################################################%] |
| 371 | +[%# Block for the first table in the "Details" section #%] |
| 372 | +[%############################################################################%] |
| 373 | + |
| 374 | +[% BLOCK section_details1 %] |
| 375 | + |
| 376 | + [%#############%] |
| 377 | + [%# PRODUCT #%] |
| 378 | + [%#############%] |
| 379 | + |
| 380 | + <tr> |
| 381 | + [% IF bug.check_can_change_field('product', 0, 1) %] |
| 382 | + [% prod_list = user.get_enterable_products %] |
| 383 | + [% IF NOT user.can_enter_product(bug.product) %] |
| 384 | + [% prod_list.unshift(bug.product_obj) %] |
| 385 | + [% END %] |
| 386 | + [% END %] |
| 387 | + |
| 388 | + [% INCLUDE bug/field.html.tmpl |
| 389 | + bug = bug, field = select_fields.product, |
| 390 | + override_legal_values = prod_list |
| 391 | + desc_url = 'describecomponents.cgi', value = bug.product |
| 392 | + editable = bug.check_can_change_field('product', 0, 1) %] |
| 393 | + </tr> |
| 394 | + [%###############%] |
| 395 | + [%# Component #%] |
| 396 | + [%###############%] |
| 397 | + <tr> |
| 398 | + <td class="field_label"> |
| 399 | + <label for="component" accesskey="m"> |
| 400 | + <b><a href="describecomponents.cgi?product=[% bug.product FILTER url_quote %]"> |
| 401 | + Co<u>m</u>ponent</a>: |
| 402 | + </b> |
| 403 | + </label> |
| 404 | + </td> |
| 405 | + [% PROCESS select selname => "component" %] |
| 406 | + </tr> |
| 407 | + <tr> |
| 408 | + <td class="field_label"> |
| 409 | + <label for="version"><b>Version</b></label>: |
| 410 | + </td> |
| 411 | + |
| 412 | + [% PROCESS select selname => "version" %] |
| 413 | + </tr> |
| 414 | + [%############%] |
| 415 | + [%# PLATFORM #%] |
| 416 | + [%############%] |
| 417 | + <tr> |
| 418 | + <td class="field_label"> |
| 419 | + <label for="rep_platform" accesskey="h"><b>Platform</b></label>: |
| 420 | + </td> |
| 421 | + <td class="field_value"> |
| 422 | + [% INCLUDE bug/field.html.tmpl |
| 423 | + bug = bug, field = select_fields.rep_platform, |
| 424 | + no_tds = 1, value = bug.rep_platform |
| 425 | + editable = bug.check_can_change_field('rep_platform', 0, 1) %] |
| 426 | + [%+ INCLUDE bug/field.html.tmpl |
| 427 | + bug = bug, field = select_fields.op_sys, |
| 428 | + no_tds = 1, value = bug.op_sys |
| 429 | + editable = bug.check_can_change_field('op_sys', 0, 1) %] |
| 430 | + <script type="text/javascript"> |
| 431 | + assignToDefaultOnChange(['product', 'component']); |
| 432 | + </script> |
| 433 | + </td> |
| 434 | + </tr> |
| 435 | + |
| 436 | + |
| 437 | + |
| 438 | +[% END %] |
| 439 | + |
| 440 | +[%############################################################################%] |
| 441 | +[%# Block for the status section #%] |
| 442 | +[%############################################################################%] |
| 443 | + |
| 444 | +[% BLOCK section_status %] |
| 445 | + <tr> |
| 446 | + <td class="field_label"> |
| 447 | + <b><a href="page.cgi?id=fields.html#status">Status</a></b>: |
| 448 | + </td> |
| 449 | + <td id="bz_field_status"> |
| 450 | + <span id="static_bug_status"> |
| 451 | + [% get_status(bug.bug_status) FILTER html %] |
| 452 | + [% IF bug.resolution %] |
| 453 | + [%+ get_resolution(bug.resolution) FILTER html %] |
| 454 | + [% IF bug.dup_id %] |
| 455 | + of [% "${terms.bug} ${bug.dup_id}" FILTER bug_link(bug.dup_id) FILTER none %] |
| 456 | + [% END %] |
| 457 | + [% END %] |
| 458 | + [% IF bug.user.canedit || bug.user.isreporter %] |
| 459 | + (<a href="#add_comment" |
| 460 | + onclick="window.setTimeout(function() { document.getElementById('bug_status').focus(); }, 10)">edit</a>) |
| 461 | + [% END %] |
| 462 | + </span> |
| 463 | + </td> |
| 464 | + </tr> |
| 465 | +[% END %] |
| 466 | + |
| 467 | +[%############################################################################%] |
| 468 | +[%# Block for the second table in the "Details" section #%] |
| 469 | +[%############################################################################%] |
| 470 | + |
| 471 | +[% BLOCK section_details2 %] |
| 472 | + |
| 473 | + [%###############################################################%] |
| 474 | + [%# Importance (priority, severity and votes) #%] |
| 475 | + [%###############################################################%] |
| 476 | + <tr> |
| 477 | + <td class="field_label"> |
| 478 | + <label for="priority" accesskey="i"> |
| 479 | + <b><a href="page.cgi?id=fields.html#importance"><u>I</u>mportance</a></b></label>: |
| 480 | + </td> |
| 481 | + <td> |
| 482 | + [% INCLUDE bug/field.html.tmpl |
| 483 | + bug = bug, field = select_fields.priority, |
| 484 | + no_tds = 1, value = bug.priority |
| 485 | + editable = bug.check_can_change_field('priority', 0, 1) %] |
| 486 | + [%+ INCLUDE bug/field.html.tmpl |
| 487 | + bug = bug, field = select_fields.bug_severity, |
| 488 | + no_tds = 1, value = bug.bug_severity |
| 489 | + editable = bug.check_can_change_field('bug_severity', 0, 1) %] |
| 490 | + [% IF bug.use_votes %] |
| 491 | + <span id="votes_container"> |
| 492 | + [% IF bug.votes %] |
| 493 | + with |
| 494 | + <a href="votes.cgi?action=show_bug&bug_id=[% bug.bug_id %]"> |
| 495 | + [% bug.votes %] |
| 496 | + [% IF bug.votes == 1 %] |
| 497 | + vote |
| 498 | + [% ELSE %] |
| 499 | + votes |
| 500 | + [% END %]</a> |
| 501 | + [% END %] |
| 502 | + (<a href="votes.cgi?action=show_user&bug_id= |
| 503 | + [% bug.bug_id %]#vote_[% bug.bug_id %]">vote</a>) |
| 504 | + </span> |
| 505 | + [% END %] |
| 506 | + </td> |
| 507 | + </tr> |
| 508 | + |
| 509 | + [% IF Param("usetargetmilestone") && bug.target_milestone %] |
| 510 | + <tr> |
| 511 | + <td class="field_label"> |
| 512 | + <label for="target_milestone"><b> |
| 513 | + [% IF bug.milestoneurl %] |
| 514 | + <a href="[% bug.milestoneurl FILTER html %]"> |
| 515 | + [% END %] |
| 516 | + Target Milestone[% "</a>" IF bug.milestoneurl %] |
| 517 | + [%%]</b></label>: |
| 518 | + </td> |
| 519 | + [% PROCESS select selname = "target_milestone" %] |
| 520 | + </tr> |
| 521 | + [% END %] |
| 522 | + |
| 523 | +[% END %] |
| 524 | + |
| 525 | +[%############################################################################%] |
| 526 | +[%# Block for the table in the "People" section #%] |
| 527 | +[%############################################################################%] |
| 528 | + |
| 529 | +[% BLOCK section_people %] |
| 530 | + |
| 531 | + <tr> |
| 532 | + <td class="field_label"> |
| 533 | + <b><a href="page.cgi?id=fields.html#assigned_to">Assigned To</a></b>: |
| 534 | + </td> |
| 535 | + <td> |
| 536 | + [% IF bug.check_can_change_field("assigned_to", 0, 1) %] |
| 537 | + <div id="bz_assignee_edit_container" class="bz_default_hidden"> |
| 538 | + <span> |
| 539 | + [% INCLUDE global/user.html.tmpl who = bug.assigned_to %] |
| 540 | + (<a href="#" id="bz_assignee_edit_action">edit</a>) |
| 541 | + </span> |
| 542 | + </div> |
| 543 | + <div id="bz_assignee_input"> |
| 544 | + [% INCLUDE global/userselect.html.tmpl |
| 545 | + id => "assigned_to" |
| 546 | + name => "assigned_to" |
| 547 | + value => bug.assigned_to.login |
| 548 | + size => 30 |
| 549 | + %] |
| 550 | + <br> |
| 551 | + <input type="checkbox" id="set_default_assignee" name="set_default_assignee" value="1"> |
| 552 | + <label id="set_default_assignee_label" for="set_default_assignee">Reset Assignee to default</label> |
| 553 | + </div> |
| 554 | + <script type="text/javascript"> |
| 555 | + hideEditableField('bz_assignee_edit_container', |
| 556 | + 'bz_assignee_input', |
| 557 | + 'bz_assignee_edit_action', |
| 558 | + 'assigned_to', |
| 559 | + '[% bug.assigned_to.login FILTER js %]' ); |
| 560 | + initDefaultCheckbox('assignee'); |
| 561 | + </script> |
| 562 | + [% ELSE %] |
| 563 | + [% INCLUDE global/user.html.tmpl who = bug.assigned_to %] |
| 564 | + [% END %] |
| 565 | + </td> |
| 566 | + </tr> |
| 567 | + |
| 568 | + [% IF Param('useqacontact') %] |
| 569 | + <tr> |
| 570 | + <td class="field_label"> |
| 571 | + <label for="qa_contact" accesskey="q"><b><u>Q</u>A Contact</b></label>: |
| 572 | + </td> |
| 573 | + <td> |
| 574 | + [% IF bug.check_can_change_field("qa_contact", 0, 1) %] |
| 575 | + [% IF bug.qa_contact != "" %] |
| 576 | + <div id="bz_qa_contact_edit_container" class="bz_default_hidden"> |
| 577 | + <span> |
| 578 | + <span id="bz_qa_contact_edit_display"> |
| 579 | + [% INCLUDE global/user.html.tmpl who = bug.qa_contact %]</span> |
| 580 | + (<a href="#" id="bz_qa_contact_edit_action">edit</a>) |
| 581 | + </span> |
| 582 | + </div> |
| 583 | + [% END %] |
| 584 | + <div id="bz_qa_contact_input"> |
| 585 | + [% INCLUDE global/userselect.html.tmpl |
| 586 | + id => "qa_contact" |
| 587 | + name => "qa_contact" |
| 588 | + value => bug.qa_contact.login |
| 589 | + size => 30 |
| 590 | + emptyok => 1 |
| 591 | + %] |
| 592 | + <br> |
| 593 | + <input type="checkbox" id="set_default_qa_contact" name="set_default_qa_contact" value="1"> |
| 594 | + <label for="set_default_qa_contact" id="set_default_qa_contact_label">Reset QA Contact to default</label> |
| 595 | + </div> |
| 596 | + <script type="text/javascript"> |
| 597 | + [% IF bug.qa_contact != "" %] |
| 598 | + hideEditableField('bz_qa_contact_edit_container', |
| 599 | + 'bz_qa_contact_input', |
| 600 | + 'bz_qa_contact_edit_action', |
| 601 | + 'qa_contact', |
| 602 | + '[% bug.qa_contact.login FILTER js %]'); |
| 603 | + [% END %] |
| 604 | + initDefaultCheckbox('qa_contact'); |
| 605 | + </script> |
| 606 | + [% ELSE %] |
| 607 | + [% INCLUDE global/user.html.tmpl who = bug.qa_contact %] |
| 608 | + [% END %] |
| 609 | + </td> |
| 610 | + </tr> |
| 611 | + [% END %] |
| 612 | +[% END %] |
| 613 | + |
| 614 | +[%############################################################################%] |
| 615 | +[%# Block for URL Keyword and Whiteboard #%] |
| 616 | +[%############################################################################%] |
| 617 | +[% BLOCK section_url_keyword_whiteboard %] |
| 618 | +[%# *** URL Whiteboard Keywords *** %] |
| 619 | + <tr> |
| 620 | + <td class="field_label"> |
| 621 | + <label for="bug_file_loc" accesskey="u"><b> |
| 622 | + [% IF bug.bug_file_loc |
| 623 | + AND NOT bug.bug_file_loc.match("^(javascript|data)") %] |
| 624 | + <a href="[% bug.bug_file_loc FILTER html %]"><u>U</u>RL</a> |
| 625 | + [% ELSE %] |
| 626 | + <u>U</u>RL |
| 627 | + [% END %] |
| 628 | + [%%]</b></label>: |
| 629 | + </td> |
| 630 | + <td> |
| 631 | + [% IF bug.check_can_change_field("bug_file_loc", 0, 1) %] |
| 632 | + <span id="bz_url_edit_container" class="bz_default_hidden"> |
| 633 | + [% IF bug.bug_file_loc |
| 634 | + AND NOT bug.bug_file_loc.match("^(javascript|data)") %] |
| 635 | + <a href="[% bug.bug_file_loc FILTER html %]" target="_blank" |
| 636 | + title="[% bug.bug_file_loc FILTER html %]"> |
| 637 | + [% bug.bug_file_loc FILTER truncate(40) FILTER html %]</a> |
| 638 | + [% ELSE %] |
| 639 | + [% bug.bug_file_loc FILTER html %] |
| 640 | + [% END %] |
| 641 | + (<a href="#" id="bz_url_edit_action">edit</a>)</span> |
| 642 | + [% END %] |
| 643 | + <span id="bz_url_input_area"> |
| 644 | + [% url_output = PROCESS input no_td=1 inputname => "bug_file_loc" size => "40" colspan => 2 %] |
| 645 | + [% IF NOT bug.check_can_change_field("bug_file_loc", 0, 1) %] |
| 646 | + <a href="[% bug.bug_file_loc FILTER html %]">[% url_output FILTER none %]</a> |
| 647 | + [% ELSE %] |
| 648 | + [% url_output FILTER none %] |
| 649 | + [% END %] |
| 650 | + </span> |
| 651 | + [% IF bug.check_can_change_field("bug_file_loc", 0, 1) %] |
| 652 | + <script type="text/javascript"> |
| 653 | + hideEditableField('bz_url_edit_container', |
| 654 | + 'bz_url_input_area', |
| 655 | + 'bz_url_edit_action', |
| 656 | + 'bug_file_loc', |
| 657 | + "[% bug.bug_file_loc FILTER js %]"); |
| 658 | + </script> |
| 659 | + [% END %] |
| 660 | + </td> |
| 661 | + </tr> |
| 662 | + |
| 663 | + [% IF Param('usestatuswhiteboard') %] |
| 664 | + <tr> |
| 665 | + <td class="field_label"> |
| 666 | + <label for="status_whiteboard" accesskey="w"><b><u>W</u>hiteboard</b></label>: |
| 667 | + </td> |
| 668 | + [% PROCESS input inputname => "status_whiteboard" size => "40" colspan => 2 %] |
| 669 | + </tr> |
| 670 | + [% END %] |
| 671 | + |
| 672 | + [% IF use_keywords %] |
| 673 | + <tr> |
| 674 | + <td class="field_label"> |
| 675 | + <label for="keywords" accesskey="k"> |
| 676 | + <b><a href="describekeywords.cgi"><u>K</u>eywords</a></b></label>: |
| 677 | + </td> |
| 678 | + [% PROCESS input inputname => "keywords" size => 40 colspan => 2 |
| 679 | + value => bug.keywords.join(', ') %] |
| 680 | + </tr> |
| 681 | + [% END %] |
| 682 | +[% END %] |
| 683 | + |
| 684 | +[%############################################################################%] |
| 685 | +[%# Block for Depends On / Blocks #%] |
| 686 | +[%############################################################################%] |
| 687 | +[% BLOCK section_dependson_blocks %] |
| 688 | + <tr> |
| 689 | + [% PROCESS dependencies |
| 690 | + dep = { title => "Depends on", fieldname => "dependson" } %] |
| 691 | + </tr> |
| 692 | + |
| 693 | + <tr> |
| 694 | + [% PROCESS dependencies accesskey = "b" |
| 695 | + dep = { title => "<u>B</u>locks", fieldname => "blocked" } %] |
| 696 | + |
| 697 | + <tr> |
| 698 | + <th> </th> |
| 699 | + |
| 700 | + <td colspan="2" align="left" id="show_dependency_tree_or_graph"> |
| 701 | + Show dependency <a href="showdependencytree.cgi?id=[% bug.bug_id %]&hide_resolved=1">tree</a> |
| 702 | + |
| 703 | + [% IF Param('webdotbase') %] |
| 704 | + / <a href="showdependencygraph.cgi?id=[% bug.bug_id %]">graph</a> |
| 705 | + [% END %] |
| 706 | + </td> |
| 707 | + </tr> |
| 708 | +[% END %] |
| 709 | + |
| 710 | + |
| 711 | +[%############################################################################%] |
| 712 | +[%# Block for Restricting Visibility #%] |
| 713 | +[%############################################################################%] |
| 714 | + |
| 715 | +[% BLOCK section_restrict_visibility %] |
| 716 | + [% RETURN UNLESS bug.groups.size %] |
| 717 | + |
| 718 | + [% inallgroups = 1 %] |
| 719 | + [% inagroup = 0 %] |
| 720 | + [% emitted_description = 0 %] |
| 721 | + |
| 722 | + [% FOREACH group = bug.groups %] |
| 723 | + [% SET inallgroups = 0 IF NOT group.ingroup %] |
| 724 | + [% SET inagroup = 1 IF group.ison %] |
| 725 | + |
| 726 | + [% NEXT IF group.mandatory %] |
| 727 | + |
| 728 | + [% IF NOT emitted_description %] |
| 729 | + [% emitted_description = 1 %] |
| 730 | + <table class="bz_group_visibility_section"> |
| 731 | + <tr> |
| 732 | + <td class="field_label"> |
| 733 | + <label id="bz_restrict_group_visibility_label"><b>Restrict Group Visibility</b>:</label> |
| 734 | + </td> |
| 735 | + <td> |
| 736 | + <div id="bz_restrict_group_visibility_help"> |
| 737 | + <b>Only users in all of the selected groups can view this [% terms.bug %]:</b> |
| 738 | + <br> |
| 739 | + <small> |
| 740 | + (Unchecking all boxes makes this a more public [% terms.bug %].) |
| 741 | + </small> |
| 742 | + </div> |
| 743 | + [% END %] |
| 744 | + |
| 745 | + [% IF group.ingroup %] |
| 746 | + <input type="hidden" name="defined_bit-[% group.bit %]" value="1"> |
| 747 | + [% END %] |
| 748 | + <input type="checkbox" value="1" name="bit-[% group.bit %]" id="bit-[% group.bit %]" |
| 749 | + [% ' checked="checked"' IF group.ison %] |
| 750 | + [% ' disabled="disabled"' IF NOT group.ingroup %]> |
| 751 | + <label for="bit-[% group.bit %]">[% group.description FILTER html_light %]</label> |
| 752 | + <br> |
| 753 | + [% END %] |
| 754 | + |
| 755 | + [% IF emitted_description %] |
| 756 | + [% IF NOT inallgroups %] |
| 757 | + <b>Only members of a group can change the visibility of [% terms.abug %] for that group.</b> |
| 758 | + <br> |
| 759 | + [% END %] |
| 760 | + </td> |
| 761 | + </tr> |
| 762 | + [% "</table>" IF NOT inagroup %] |
| 763 | + [% END %] |
| 764 | + |
| 765 | + [% IF inagroup %] |
| 766 | + [% IF NOT emitted_description %] |
| 767 | + [% emitted_description = 1 %] |
| 768 | + <table class="bz_group_visibility_section"> |
| 769 | + [% END %] |
| 770 | + <tr> |
| 771 | + <td class="field_label"> |
| 772 | + <label id="bz_enable_role_visibility_label"><b>Enable Role Visibility</b>:</label> |
| 773 | + </td> |
| 774 | + <td> |
| 775 | + <div id="bz_enable_role_visibility_help"> |
| 776 | + <b>Users in the roles selected below can always view this [% terms.bug %]:</b> |
| 777 | + <br> |
| 778 | + <small> |
| 779 | + (The assignee |
| 780 | + [% IF (Param('useqacontact')) %] |
| 781 | + and QA contact |
| 782 | + [% END %] |
| 783 | + can always see [% terms.abug %], and this section does not take effect unless |
| 784 | + the [% terms.bug %] is restricted to at least one group.) |
| 785 | + </small> |
| 786 | + </div> |
| 787 | + <div> |
| 788 | + <div> |
| 789 | + [% user_can_edit_accessible = bug.check_can_change_field("reporter_accessible", 0, 1) %] |
| 790 | + [% IF user_can_edit_accessible %] |
| 791 | + <input type="hidden" name="defined_reporter_accessible" value="1"> |
| 792 | + [% END %] |
| 793 | + <input type="checkbox" value="1" |
| 794 | + name="reporter_accessible" id="reporter_accessible" |
| 795 | + [% " checked" IF bug.reporter_accessible %] |
| 796 | + [% " disabled=\"disabled\"" UNLESS user_can_edit_accessible %]> |
| 797 | + <label for="reporter_accessible">Reporter</label> |
| 798 | + </div> |
| 799 | + <div> |
| 800 | + [% user_can_edit_accessible = bug.check_can_change_field("cclist_accessible", 0, 1) %] |
| 801 | + [% IF user_can_edit_accessible %] |
| 802 | + <input type="hidden" name="defined_cclist_accessible" value="1"> |
| 803 | + [% END %] |
| 804 | + <input type="checkbox" value="1" |
| 805 | + name="cclist_accessible" id="cclist_accessible" |
| 806 | + [% " checked" IF bug.cclist_accessible %] |
| 807 | + [% " disabled=\"disabled\"" UNLESS user_can_edit_accessible %]> |
| 808 | + <label for="cclist_accessible">CC List</label> |
| 809 | + </div> |
| 810 | + </div> |
| 811 | + </td> |
| 812 | + </tr> |
| 813 | + </table> |
| 814 | + [% END %] |
| 815 | +[% END %] |
| 816 | + |
| 817 | +[%############################################################################%] |
| 818 | +[%# Block for Dates #%] |
| 819 | +[%############################################################################%] |
| 820 | + |
| 821 | +[% BLOCK section_dates %] |
| 822 | + <tr> |
| 823 | + <td class="field_label"> |
| 824 | + <b>Reported</b>: |
| 825 | + </td> |
| 826 | + <td> |
| 827 | + [% bug.creation_ts FILTER time %] by [% INCLUDE global/user.html.tmpl who = bug.reporter %] |
| 828 | + </td> |
| 829 | + </tr> |
| 830 | + |
| 831 | + <tr> |
| 832 | + <td class="field_label"> |
| 833 | + <b> Modified</b>: |
| 834 | + </td> |
| 835 | + <td> |
| 836 | + [% bug.delta_ts FILTER time FILTER replace(':\d\d$', '') FILTER replace(':\d\d ', ' ')%] |
| 837 | + (<a href="show_activity.cgi?id=[% bug.bug_id %]">[%# terms.Bug %]History</a>) |
| 838 | + </td> |
| 839 | + |
| 840 | + </tr> |
| 841 | +[% END %] |
| 842 | + |
| 843 | +[%############################################################################%] |
| 844 | +[%# Block for CC LIST #%] |
| 845 | +[%############################################################################%] |
| 846 | +[% BLOCK section_cclist %] |
| 847 | + <tr> |
| 848 | + <td class="field_label"> |
| 849 | + <label for="newcc" accesskey="a"><b>CC List</b>:</label> |
| 850 | + </td> |
| 851 | + <td> |
| 852 | + [% IF user.id %] |
| 853 | + [% IF NOT bug.cc || NOT bug.cc.contains(user.login) %] |
| 854 | + [% has_role = bug.user.isreporter |
| 855 | + || bug.assigned_to.id == user.id |
| 856 | + || (Param('useqacontact') |
| 857 | + && bug.qa_contact |
| 858 | + && bug.qa_contact.id == user.id) %] |
| 859 | + <input type="checkbox" id="addselfcc" name="addselfcc" |
| 860 | + [% " checked=\"checked\"" |
| 861 | + IF user.settings.state_addselfcc.value == 'always' |
| 862 | + || (!has_role |
| 863 | + && user.settings.state_addselfcc.value == 'cc_unless_role') %]> |
| 864 | + <label for="addselfcc">Add me to CC list</label> |
| 865 | + <br> |
| 866 | + [% END %] |
| 867 | + [% END %] |
| 868 | + [% bug.cc.size || 0 FILTER html %] |
| 869 | + [% IF bug.cc.size == 1 %] |
| 870 | + user |
| 871 | + [% ELSE %] |
| 872 | + users |
| 873 | + [% END %] |
| 874 | + [% IF user.id %] |
| 875 | + [% IF bug.cc.contains( user.email ) %] |
| 876 | + including you |
| 877 | + [% END %] |
| 878 | + [% END %] |
| 879 | + <span id="cc_edit_area_showhide_container" class="bz_default_hidden"> |
| 880 | + (<a href="#" id="cc_edit_area_showhide">[% IF user.id %]edit[% ELSE %]show[% END %]</a>) |
| 881 | + </span> |
| 882 | + <div id="cc_edit_area"> |
| 883 | + <br> |
| 884 | + [% IF user.id %] |
| 885 | + <div> |
| 886 | + <div><label for="cc"><b>Add</b></label></div> |
| 887 | + [% INCLUDE global/userselect.html.tmpl |
| 888 | + id => "newcc" |
| 889 | + name => "newcc" |
| 890 | + value => "" |
| 891 | + size => 30 |
| 892 | + multiple => 5 |
| 893 | + %] |
| 894 | + </div> |
| 895 | + [% END %] |
| 896 | + [% IF bug.cc %] |
| 897 | + <select id="cc" name="cc" multiple="multiple" size="5"> |
| 898 | + [% FOREACH c = bug.cc %] |
| 899 | + <option value="[% c FILTER email FILTER html %]"> |
| 900 | + [% c FILTER email FILTER html %]</option> |
| 901 | + [% END %] |
| 902 | + </select> |
| 903 | + [% IF user.id %] |
| 904 | + <br> |
| 905 | + <input type="checkbox" id="removecc" name="removecc"> |
| 906 | + [%%]<label for="removecc">Remove selected CCs</label> |
| 907 | + <br> |
| 908 | + [% END %] |
| 909 | + [% END %] |
| 910 | + </div> |
| 911 | + <script type="text/javascript"> |
| 912 | + hideEditableField( 'cc_edit_area_showhide_container', |
| 913 | + 'cc_edit_area', |
| 914 | + 'cc_edit_area_showhide', |
| 915 | + '', |
| 916 | + ''); |
| 917 | + </script> |
| 918 | + </td> |
| 919 | + </tr> |
| 920 | +[% END %] |
| 921 | + |
| 922 | +[%############################################################################%] |
| 923 | +[%# Block for See Also #%] |
| 924 | +[%############################################################################%] |
| 925 | +[% BLOCK section_see_also %] |
| 926 | + [% IF Param('use_see_also') || bug.see_also.size %] |
| 927 | + <tr> |
| 928 | + [% INCLUDE bug/field.html.tmpl |
| 929 | + field = bug_fields.see_also |
| 930 | + value = bug.see_also |
| 931 | + editable = bug.check_can_change_field('see_also', 0, 1) |
| 932 | + %] |
| 933 | + </tr> |
| 934 | + [% END %] |
| 935 | +[% END %] |
| 936 | + |
| 937 | +[%############################################################################%] |
| 938 | +[%# Block for FLAGS #%] |
| 939 | +[%############################################################################%] |
| 940 | + |
| 941 | +[% BLOCK section_flags %] |
| 942 | + [%# *** Flags *** %] |
| 943 | + [% show_bug_flags = 0 %] |
| 944 | + [% FOREACH type = bug.flag_types %] |
| 945 | + [% IF (type.flags && type.flags.size > 0) || (user.id && type.is_active) %] |
| 946 | + [% show_bug_flags = 1 %] |
| 947 | + [% LAST %] |
| 948 | + [% END %] |
| 949 | + [% END %] |
| 950 | + [% IF show_bug_flags %] |
| 951 | + <tr> |
| 952 | + <td class="field_label flags_label"> |
| 953 | + <label><b>Flags:</b></label> |
| 954 | + </td> |
| 955 | + <td></td> |
| 956 | + </tr> |
| 957 | + <tr> |
| 958 | + <td colspan="2"> |
| 959 | + [% IF bug.flag_types.size > 0 %] |
| 960 | + [% PROCESS "flag/list.html.tmpl" flag_no_header = 1 |
| 961 | + flag_types = bug.flag_types |
| 962 | + any_flags_requesteeble = bug.any_flags_requesteeble %] |
| 963 | + [% END %] |
| 964 | + </td> |
| 965 | + </tr> |
| 966 | + [% END %] |
| 967 | +[% END %] |
| 968 | + |
| 969 | +[%############################################################################%] |
| 970 | +[%# Block for Custom Fields #%] |
| 971 | +[%############################################################################%] |
| 972 | + |
| 973 | +[% BLOCK section_customfields %] |
| 974 | +[%# *** Custom Fields *** %] |
| 975 | + |
| 976 | + [% FOREACH field = Bugzilla.active_custom_fields %] |
| 977 | + <tr> |
| 978 | + [% PROCESS bug/field.html.tmpl value=bug.${field.name} |
| 979 | + editable = bug.check_can_change_field(field.name, 0, 1) |
| 980 | + value_span = 2 %] |
| 981 | + </tr> |
| 982 | + [% END %] |
| 983 | +[% END %] |
| 984 | + |
| 985 | +[%############################################################################%] |
| 986 | +[%# Block for Section Spacer #%] |
| 987 | +[%############################################################################%] |
| 988 | + |
| 989 | +[% BLOCK section_spacer %] |
| 990 | + <tr> |
| 991 | + <td colspan="2" class="bz_section_spacer"></td> |
| 992 | + </tr> |
| 993 | +[% END %] |
| 994 | + |
| 995 | + |
| 996 | + |
| 997 | + |
| 998 | +[%############################################################################%] |
| 999 | +[%# Block for dependencies #%] |
| 1000 | +[%############################################################################%] |
| 1001 | + |
| 1002 | +[% BLOCK dependencies %] |
| 1003 | + |
| 1004 | + <th class="field_label"> |
| 1005 | + <label for="[% dep.fieldname %]"[% " accesskey=\"$accesskey\"" IF accesskey %]> |
| 1006 | + [% dep.title %]</label>: |
| 1007 | + </th> |
| 1008 | + <td> |
| 1009 | + <span id="[% dep.fieldname %]_input_area"> |
| 1010 | + [% IF bug.check_can_change_field(dep.fieldname, 0, 1) %] |
| 1011 | + <input name="[% dep.fieldname %]" id="[% dep.fieldname %]" |
| 1012 | + class="text_input" |
| 1013 | + value="[% bug.${dep.fieldname}.join(', ') %]"> |
| 1014 | + [% END %] |
| 1015 | + </span> |
| 1016 | + |
| 1017 | + [% FOREACH depbug = bug.${dep.fieldname} %] |
| 1018 | + [% depbug FILTER bug_link(depbug, use_alias => 1) FILTER none %][% " " %] |
| 1019 | + [% END %] |
| 1020 | + [% IF bug.check_can_change_field(dep.fieldname, 0, 1) %] |
| 1021 | + <span id="[% dep.fieldname %]_edit_container" class="edit_me bz_default_hidden" > |
| 1022 | + (<a href="#" id="[% dep.fieldname %]_edit_action">edit</a>) |
| 1023 | + </span> |
| 1024 | + <script type="text/javascript"> |
| 1025 | + hideEditableField('[% dep.fieldname %]_edit_container', |
| 1026 | + '[% dep.fieldname %]_input_area', |
| 1027 | + '[% dep.fieldname %]_edit_action', |
| 1028 | + '[% dep.fieldname %]', |
| 1029 | + "[% bug.${dep.fieldname}.join(', ') %]"); |
| 1030 | + </script> |
| 1031 | + [% END %] |
| 1032 | + </td> |
| 1033 | + |
| 1034 | + [% accesskey = undef %] |
| 1035 | + |
| 1036 | +[% END %] |
| 1037 | + |
| 1038 | +[%############################################################################%] |
| 1039 | +[%# Block for Time Tracking Group #%] |
| 1040 | +[%############################################################################%] |
| 1041 | + |
| 1042 | +[% BLOCK section_timetracking %] |
| 1043 | + <table class="bz_time_tracking_table"> |
| 1044 | + <tr> |
| 1045 | + <th> |
| 1046 | + <label for="estimated_time">Orig. Est.</label> |
| 1047 | + </th> |
| 1048 | + <th> |
| 1049 | + Current Est. |
| 1050 | + </th> |
| 1051 | + <th> |
| 1052 | + <label for="work_time">Hours Worked</label> |
| 1053 | + </th> |
| 1054 | + <th> |
| 1055 | + <label for="remaining_time">Hours Left</label> |
| 1056 | + </th> |
| 1057 | + <th> |
| 1058 | + %Complete |
| 1059 | + </th> |
| 1060 | + <th> |
| 1061 | + Gain |
| 1062 | + </th> |
| 1063 | + <th> |
| 1064 | + <label for="deadline">Deadline</label> |
| 1065 | + </th> |
| 1066 | + </tr> |
| 1067 | + <tr> |
| 1068 | + <td> |
| 1069 | + <input name="estimated_time" id="estimated_time" |
| 1070 | + value="[% PROCESS formattimeunit |
| 1071 | + time_unit=bug.estimated_time %]" |
| 1072 | + size="6" maxlength="6"> |
| 1073 | + </td> |
| 1074 | + <td> |
| 1075 | + [% PROCESS formattimeunit |
| 1076 | + time_unit=(bug.actual_time + bug.remaining_time) %] |
| 1077 | + </td> |
| 1078 | + <td> |
| 1079 | + [% PROCESS formattimeunit time_unit=bug.actual_time %] + |
| 1080 | + <input name="work_time" id="work_time" |
| 1081 | + value="0" size="3" maxlength="6" |
| 1082 | + onchange="adjustRemainingTime();"> |
| 1083 | + </td> |
| 1084 | + <td> |
| 1085 | + <input name="remaining_time" id="remaining_time" |
| 1086 | + value="[% PROCESS formattimeunit |
| 1087 | + time_unit=bug.remaining_time %]" |
| 1088 | + size="6" maxlength="6" onchange="updateRemainingTime();"> |
| 1089 | + </td> |
| 1090 | + <td> |
| 1091 | + [% PROCESS calculatepercentage act=bug.actual_time |
| 1092 | + rem=bug.remaining_time %] |
| 1093 | + </td> |
| 1094 | + <td> |
| 1095 | + [% PROCESS formattimeunit time_unit=bug.estimated_time - (bug.actual_time + bug.remaining_time) %] |
| 1096 | + </td> |
| 1097 | + <td> |
| 1098 | + <input name="deadline" id="deadline" value="[% bug.deadline %]" |
| 1099 | + size="10" maxlength="10"><br /> |
| 1100 | + <small>(YYYY-MM-DD)</small> |
| 1101 | + </td> |
| 1102 | + </tr> |
| 1103 | + <tr> |
| 1104 | + <td colspan="7" class="bz_summarize_time"> |
| 1105 | + <a href="summarize_time.cgi?id=[% bug.bug_id %]&do_depends=1"> |
| 1106 | + Summarize time (including time for [% terms.bugs %] |
| 1107 | + blocking this [% terms.bug %])</a> |
| 1108 | + </td> |
| 1109 | + </tr> |
| 1110 | + </table> |
| 1111 | +[% END %] |
| 1112 | + |
| 1113 | +[%############################################################################%] |
| 1114 | +[%# Block for SELECT fields #%] |
| 1115 | +[%############################################################################%] |
| 1116 | + |
| 1117 | +[% BLOCK select %] |
| 1118 | + [% IF NOT no_td %] |
| 1119 | + <td> |
| 1120 | + [% END %] |
| 1121 | + [% IF bug.check_can_change_field(selname, 0, 1) AND bug.choices.${selname}.size > 1 %] |
| 1122 | + <select id="[% selname %]" name="[% selname %]"> |
| 1123 | + [% FOREACH x = bug.choices.${selname} %] |
| 1124 | + <option value="[% x FILTER html %]" |
| 1125 | + [% " selected" IF x == bug.${selname} %]>[% x FILTER html %] |
| 1126 | + </option> |
| 1127 | + [% END %] |
| 1128 | + </select> |
| 1129 | + [% ELSE %] |
| 1130 | + [% bug.${selname} FILTER html %] |
| 1131 | + [% END %] |
| 1132 | + [% IF NOT no_td %] |
| 1133 | + </td> |
| 1134 | + [% END %] |
| 1135 | + [% no_td = 0 %] |
| 1136 | +[% END %] |
| 1137 | + |
| 1138 | +[%############################################################################%] |
| 1139 | +[%# Block for INPUT fields #%] |
| 1140 | +[%############################################################################%] |
| 1141 | + |
| 1142 | +[% BLOCK input %] |
| 1143 | + [% IF no_td != 1 %] |
| 1144 | + <td[% " colspan=\"$colspan\"" IF colspan %]> |
| 1145 | + [% END %] |
| 1146 | + [% val = value ? value : bug.$inputname %] |
| 1147 | + [% IF bug.check_can_change_field(inputname, 0, 1) %] |
| 1148 | + <input id="[% inputname %]" name="[% inputname %]" class="text_input" |
| 1149 | + value="[% val FILTER html %]"[% " size=\"$size\"" IF size %] |
| 1150 | + [% " maxlength=\"$maxlength\"" IF maxlength %] |
| 1151 | + [% " spellcheck=\"$spellcheck\"" IF spellcheck %]> |
| 1152 | + [% ELSE %] |
| 1153 | + [% IF size && val.length > size %] |
| 1154 | + <span title="[% val FILTER html %]"> |
| 1155 | + [% val FILTER truncate(size) FILTER html %] |
| 1156 | + </span> |
| 1157 | + [% ELSE %] |
| 1158 | + [% val FILTER html %] |
| 1159 | + [% END %] |
| 1160 | + [% END %] |
| 1161 | + [% IF no_td != 1 %] |
| 1162 | + </td> |
| 1163 | + [% END %] |
| 1164 | + [% no_td = 0 %] |
| 1165 | + [% maxlength = 0 %] |
| 1166 | + [% colspan = 0 %] |
| 1167 | + [% size = 0 %] |
| 1168 | + [% value = undef %] |
| 1169 | + [% spellcheck = undef %] |
| 1170 | +[% END %] |
| 1171 | +[% BLOCK commit_button %] |
| 1172 | + [% IF user.id %] |
| 1173 | + <div class="knob-buttons"> |
| 1174 | + <input type="submit" value="Commit" id="commit[% id FILTER css_class_quote %]"> |
| 1175 | + [% IF bug.user.canmove %] |
| 1176 | + <input type="submit" name="action" id="action[% id FILTER css_class_quote %]" value="[% Param("move-button-text") %]"> |
| 1177 | + [% END %] |
| 1178 | + </div> |
| 1179 | + [% END %] |
| 1180 | +[% END %] |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/bug/edit.html.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 1181 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/bug/show.html.tmpl |
— | — | @@ -0,0 +1,73 @@ |
| 2 | +[%# The contents of this file are subject to the Mozilla Public |
| 3 | + # License Version 1.1 (the "License"); you may not use this file |
| 4 | + # except in compliance with the License. You may obtain a copy of |
| 5 | + # the License at http://www.mozilla.org/MPL/ |
| 6 | + # |
| 7 | + # Software distributed under the License is distributed on an "AS |
| 8 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + # implied. See the License for the specific language governing |
| 10 | + # rights and limitations under the License. |
| 11 | + # |
| 12 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + # |
| 14 | + # The Initial Developer of the Original Code is Netscape Communications |
| 15 | + # Corporation. Portions created by Netscape are |
| 16 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + # Rights Reserved. |
| 18 | + # |
| 19 | + # Contributor(s): Gervase Markham <gerv@gerv.net> |
| 20 | + # Vaskin Kissoyan <vkissoyan@yahoo.com> |
| 21 | + # Bradley Baetz <bbaetz@student.usyd.edu.au> |
| 22 | + # Max Kanat-Alexander <mkanat@bugzilla.org> |
| 23 | + #%] |
| 24 | + |
| 25 | +[% PROCESS global/variables.none.tmpl %] |
| 26 | + |
| 27 | +[%# This script/template only handles one bug #%] |
| 28 | +[% bug = bugs.0 %] |
| 29 | + |
| 30 | +[% IF !header_done %] |
| 31 | + [% filtered_desc = bug.short_desc FILTER html %] |
| 32 | + [% filtered_timestamp = bug.delta_ts FILTER time %] |
| 33 | + [% bodyclasses = ['bz_bug', |
| 34 | + "bz_status_$bug.bug_status", |
| 35 | + "bz_product_$bug.product", |
| 36 | + "bz_component_$bug.component", |
| 37 | + "bz_bug_$bug.bug_id" |
| 38 | + ] |
| 39 | + %] |
| 40 | + [% FOREACH group = bug.groups_in %] |
| 41 | + [% bodyclasses.push("bz_group_$group.name") %] |
| 42 | + [% END %] |
| 43 | + [% PROCESS global/header.html.tmpl |
| 44 | + title = "$terms.Bug $bug.bug_id – $filtered_desc" |
| 45 | + header = "$terms.Bug $bug.bug_id" |
| 46 | + subheader = filtered_desc |
| 47 | + header_addl_info = "Last modified: $filtered_timestamp" |
| 48 | + bodyclasses = bodyclasses |
| 49 | + javascript_urls = [ "js/util.js", "js/field.js", "js/yui/calendar.js" ] |
| 50 | + style_urls = [ "skins/standard/yui/calendar.css", "skins/standard/show_bug.css" ] |
| 51 | + doc_section = "bug_page.html" |
| 52 | + %] |
| 53 | +[% END %] |
| 54 | + |
| 55 | +[% IF nextbug %] |
| 56 | + <hr> |
| 57 | + <p> |
| 58 | + The next [% terms.bug %] in your list is [% terms.bug %] |
| 59 | + <a href="show_bug.cgi?id=[% bug.bug_id %]">[% bug.bug_id %]</a>: |
| 60 | + </p> |
| 61 | + <hr> |
| 62 | +[% END %] |
| 63 | + |
| 64 | +[% PROCESS bug/navigate.html.tmpl %] |
| 65 | + |
| 66 | +[% PROCESS bug/edit.html.tmpl %] |
| 67 | + |
| 68 | +<hr> |
| 69 | + |
| 70 | +[% PROCESS bug/navigate.html.tmpl bottom_navigator => 1%] |
| 71 | + |
| 72 | +<br> |
| 73 | + |
| 74 | +[% PROCESS global/footer.html.tmpl %] |
Property changes on: trunk/tools/bugzilla/bugzilla-3.4.4/template/en/custom/bug/show.html.tmpl |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 75 | + native |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/scripts/bugzilla_report.php |
— | — | @@ -0,0 +1,267 @@ |
| 2 | +<?php error_reporting(E_ALL); |
| 3 | + |
| 4 | +function getBugsPerProduct( $begin_date, $end_date ) { |
| 5 | + print "New Bugs Per Product\n\n"; |
| 6 | + return <<<END |
| 7 | +SELECT |
| 8 | + name, count(*) |
| 9 | +FROM |
| 10 | + bugs |
| 11 | +JOIN |
| 12 | + products |
| 13 | + on |
| 14 | + product_id = products.id |
| 15 | +WHERE |
| 16 | + bug_status = 'NEW' |
| 17 | + and creation_ts |
| 18 | +BETWEEN |
| 19 | + "$begin_date" |
| 20 | + and |
| 21 | + "$end_date" |
| 22 | +GROUP BY |
| 23 | + product_id |
| 24 | +LIMIT 5; |
| 25 | +END; |
| 26 | +} |
| 27 | + |
| 28 | +function getBugsPerComponent( $begin_date, $end_date ) { |
| 29 | + print "New Bugs Per Component\n\n"; |
| 30 | + return <<<END |
| 31 | +SELECT |
| 32 | + name, count(*) as total |
| 33 | +FROM |
| 34 | + bugs |
| 35 | +JOIN |
| 36 | + components |
| 37 | + on |
| 38 | + component_id = components.id |
| 39 | +WHERE |
| 40 | + bug_status = 'NEW' |
| 41 | + and |
| 42 | + creation_ts |
| 43 | +BETWEEN |
| 44 | + "$begin_date" |
| 45 | + and |
| 46 | + "$end_date" |
| 47 | +GROUP BY |
| 48 | + component_id |
| 49 | +ORDER BY |
| 50 | + total |
| 51 | +DESC |
| 52 | +LIMIT |
| 53 | + 5; |
| 54 | + |
| 55 | +END; |
| 56 | +} |
| 57 | + |
| 58 | +function getBugsResolvedPerUser( $begin_date, $end_date ) { |
| 59 | + print "Top 5 Bug Resolvers\n\n"; |
| 60 | + return <<<END |
| 61 | +SELECT |
| 62 | + login_name, count(*) as total |
| 63 | +FROM |
| 64 | + bugs_activity |
| 65 | +JOIN |
| 66 | + profiles |
| 67 | + on |
| 68 | + who = profiles.userid |
| 69 | +WHERE |
| 70 | + added = 'RESOLVED' |
| 71 | + and |
| 72 | + bug_when |
| 73 | +BETWEEN |
| 74 | + "$begin_date" |
| 75 | + and |
| 76 | + "$end_date" |
| 77 | +GROUP BY |
| 78 | + who |
| 79 | +ORDER BY |
| 80 | + total |
| 81 | +DESC |
| 82 | +LIMIT |
| 83 | + 5; |
| 84 | +END; |
| 85 | +} |
| 86 | + |
| 87 | +function getBugResolutions( $begin_date, $end_date, $resolution ) { |
| 88 | + $resolution = mysql_real_escape_string( $resolution ); |
| 89 | + $resolution = "'$resolution'"; |
| 90 | + |
| 91 | + return <<<END |
| 92 | +SELECT |
| 93 | + count(*) |
| 94 | +FROM |
| 95 | + bugs |
| 96 | +WHERE |
| 97 | + resolution = $resolution |
| 98 | + and delta_ts |
| 99 | +BETWEEN |
| 100 | + "$begin_date" |
| 101 | + and |
| 102 | + "$end_date" |
| 103 | +END; |
| 104 | +} |
| 105 | + |
| 106 | +function getBugsChangingStatus( $begin_date, $end_date, $state ) { |
| 107 | + $state = mysql_real_escape_string( $state ); |
| 108 | + $state = "'$state'"; |
| 109 | + |
| 110 | + return <<<END |
| 111 | +SELECT |
| 112 | + count(*) |
| 113 | +FROM |
| 114 | + bugs |
| 115 | +WHERE |
| 116 | + bug_status = $state |
| 117 | + and delta_ts |
| 118 | +BETWEEN |
| 119 | + "$begin_date" |
| 120 | + and |
| 121 | + "$end_date" |
| 122 | +END; |
| 123 | +} |
| 124 | + |
| 125 | +function getTotalOpenBugs() { |
| 126 | + return <<<END |
| 127 | +SELECT |
| 128 | + count(*) |
| 129 | +FROM |
| 130 | + bugs |
| 131 | +WHERE |
| 132 | + bug_status = 'ASSIGNED' or |
| 133 | + bug_status = 'NEW' or |
| 134 | + bug_status = 'REOPENED'; |
| 135 | +END; |
| 136 | +} |
| 137 | + |
| 138 | + |
| 139 | +function formatOutput( $result ) { |
| 140 | + while ( $row = mysql_fetch_row( $result ) ) { |
| 141 | + if ( is_array( $row ) ) { |
| 142 | + foreach( $row as $row_i ) { |
| 143 | + $row_i = str_replace( '@', ' [AT] ', $row_i ); //strip out any easy scrapes |
| 144 | + print pack( 'A36', ( $row_i ) ); |
| 145 | + } |
| 146 | + } |
| 147 | + else { |
| 148 | + print "0\n"; |
| 149 | + } |
| 150 | + print "\n"; |
| 151 | + } |
| 152 | +} |
| 153 | + |
| 154 | +function reportFailure( $text ) { |
| 155 | + print "Wikimedia Bugzilla report (FAILED), $text "; |
| 156 | + die( "FAILED\n\n$text\n" ); |
| 157 | +} |
| 158 | + |
| 159 | +# main |
| 160 | + |
| 161 | +$options = getopt( 'b:e:h' ); |
| 162 | + |
| 163 | +if ( isset( $options['h'] ) ) { |
| 164 | + $line = "bugzilla_report.php: usage bugzilla_report.php [-b|-e] \n"; |
| 165 | + $line .= " -b start date\n"; |
| 166 | + $line .= " -e end date\n"; |
| 167 | + |
| 168 | + die( $line ); |
| 169 | +} |
| 170 | + |
| 171 | +if ( !isset( $options['e'] ) ) { |
| 172 | + $end_date = strtotime( 'now' ); |
| 173 | +} else { |
| 174 | + $end_date = strtotime( $options['e'] ); |
| 175 | +} |
| 176 | + |
| 177 | +if ( !isset( $options['b'] ) ) { |
| 178 | + $begin_date = $end_date - 86400*7 ; |
| 179 | +} else { |
| 180 | + $begin_date = strtotime( $options['b'] ); |
| 181 | +} |
| 182 | + |
| 183 | +print "MediaWiki Bugzilla Report for " . date('F d, Y', $begin_date) . " - " . date('F d, Y', $end_date) . "\n\n"; |
| 184 | + |
| 185 | +#Needs user/pass info |
| 186 | +$ok = mysql_connect('', '', ''); |
| 187 | +if ( !$ok ) { |
| 188 | + reportFailure( 'DB connection failure' ); |
| 189 | +} |
| 190 | + |
| 191 | +$ok = mysql_select_db( 'bugzilla3' ); |
| 192 | +if ( !$ok ) { |
| 193 | + reportFailure( 'DB selection failure' ); |
| 194 | +} |
| 195 | + |
| 196 | +$reportsPerItem = array( |
| 197 | + 'getBugsPerComponent', |
| 198 | + 'getBugsPerProduct', |
| 199 | + 'getBugsResolvedPerUser', |
| 200 | +); |
| 201 | + |
| 202 | +$statesToRun = array( |
| 203 | + 'NEW', |
| 204 | + 'ASSIGNED', |
| 205 | + 'REOPENED', |
| 206 | + 'RESOLVED', |
| 207 | +); |
| 208 | + |
| 209 | +$resolutionsToRun = array( |
| 210 | + 'FIXED', |
| 211 | + 'REMIND', |
| 212 | + 'INVALID', |
| 213 | + 'DUPLICATE', |
| 214 | + 'WONTFIX', |
| 215 | + 'WORKSFORME', |
| 216 | + 'LATER', |
| 217 | + 'MOVED', |
| 218 | +); |
| 219 | + |
| 220 | +$totalStatistics = array( |
| 221 | + 'getTotalOpenBugs', |
| 222 | +); |
| 223 | + |
| 224 | + |
| 225 | +print "Status changes this week\n\n"; |
| 226 | + |
| 227 | +foreach( $statesToRun as $state ) { |
| 228 | + $sql = getBugsChangingStatus( date( 'Y-m-d', $begin_date ), date( 'Y-m-d', $end_date ), $state); |
| 229 | + $result = mysql_query( $sql ); |
| 230 | + if ( !$result ) { |
| 231 | + reportFailure( 'Query failure' ); |
| 232 | + } |
| 233 | + print pack( 'A23A3', "Bugs $state", ':' ); |
| 234 | + formatOutput( $result ); |
| 235 | +} |
| 236 | + |
| 237 | +foreach( $totalStatistics as $report ) { |
| 238 | + $sql = getTotalOpenBugs(); |
| 239 | + $result = mysql_query( $sql ); |
| 240 | + if ( !$result ) |
| 241 | + reportFailure( 'Query failure' ); |
| 242 | + print "\nTotal bugs still open: "; |
| 243 | + formatOutput( $result ); |
| 244 | +} |
| 245 | + |
| 246 | +print "\nResolutions for the week:\n\n"; |
| 247 | + |
| 248 | +foreach( $resolutionsToRun as $resolution ) { |
| 249 | + $sql = getBugResolutions( date( 'Y-m-d', $begin_date ), date( 'Y-m-d', $end_date ), $resolution ); |
| 250 | + $result = mysql_query( $sql ); |
| 251 | + if ( !$result ) { |
| 252 | + reportFailure( 'Query failure' ); |
| 253 | + } |
| 254 | + print pack( 'A23A3', "Bugs marked $resolution", ':' ); |
| 255 | + formatOutput( $result ); |
| 256 | +} |
| 257 | + |
| 258 | +print "\nSpecific Product/Component Resolutions & User Metrics \n\n"; |
| 259 | + |
| 260 | +foreach( $reportsPerItem as $report) { |
| 261 | + $sql = $report( date( 'Y-m-d', $begin_date), date( 'Y-m-d', $end_date ) ); |
| 262 | + $result = mysql_query( $sql ); |
| 263 | + if ( !$result ) { |
| 264 | + reportFailure( 'Query failure' ); |
| 265 | + } |
| 266 | + formatOutput( $result ); |
| 267 | + print "\n"; |
| 268 | +} |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/scripts/bugzilla_report.php |
___________________________________________________________________ |
Added: svn:executable |
1 | 269 | + * |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/admin.css |
— | — | @@ -0,0 +1,115 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Marc Schumann <wurblzap@gmail.com> |
| 15 | + */ |
| 16 | + |
| 17 | +.warningmessages, .criticalmessages { |
| 18 | + background-color: white; |
| 19 | + border-style: solid; |
| 20 | + border-width: 1px; |
| 21 | + padding: 1ex 1ex 1ex 4ex; |
| 22 | + margin: 1ex; |
| 23 | +} |
| 24 | + |
| 25 | +.warningmessages { |
| 26 | + border-color: yellow; |
| 27 | +} |
| 28 | + |
| 29 | +.criticalmessages { |
| 30 | + border-color: red; |
| 31 | +} |
| 32 | + |
| 33 | +.alert { |
| 34 | + color: red; |
| 35 | + background-color: inherit; |
| 36 | +} |
| 37 | + |
| 38 | +p.areyoureallyreallysure { |
| 39 | + color: red; |
| 40 | + font-size: 120%; |
| 41 | + font-weight: bold; |
| 42 | +} |
| 43 | + |
| 44 | +tr.param_disabled { |
| 45 | + background-color: lightgrey; |
| 46 | +} |
| 47 | + |
| 48 | +td.admin_links { |
| 49 | + width: 50%; |
| 50 | + padding: 1em; |
| 51 | + vertical-align: top; |
| 52 | +} |
| 53 | + |
| 54 | +td.admin_links dt { |
| 55 | + margin-top: 1em; |
| 56 | +} |
| 57 | + |
| 58 | +td.admin_links dt.forbidden, td.admin_links dd.forbidden { |
| 59 | + font-size: smaller; |
| 60 | + font-style: italic; |
| 61 | + color: #aaa; |
| 62 | +} |
| 63 | + |
| 64 | +td.admin_links dt.forbidden a, td.admin_links dd.forbidden a { |
| 65 | + text-decoration: none; |
| 66 | + color: inherit; |
| 67 | + cursor: default; |
| 68 | +} |
| 69 | + |
| 70 | +.col-header { |
| 71 | + width: 8em; |
| 72 | +} |
| 73 | + |
| 74 | +.checkbox-cell { |
| 75 | + border: 1px black solid; |
| 76 | +} |
| 77 | + |
| 78 | +/* Grey-green color */ |
| 79 | +.open-status { |
| 80 | + color: #286; |
| 81 | +} |
| 82 | + |
| 83 | +/* Brown-red color */ |
| 84 | +.closed-status { |
| 85 | + color: #a63; |
| 86 | +} |
| 87 | + |
| 88 | +/* Dark green color */ |
| 89 | +.checked { |
| 90 | + background-color: #5b4; |
| 91 | +} |
| 92 | + |
| 93 | +/* Dark red color */ |
| 94 | +td.forbidden { |
| 95 | + background-color: #811; |
| 96 | +} |
| 97 | + |
| 98 | +/* Light green color */ |
| 99 | +td.set { |
| 100 | + background-color: #efe; |
| 101 | +} |
| 102 | + |
| 103 | +/* Light red color */ |
| 104 | +td.unset { |
| 105 | + background-color: #fee; |
| 106 | +} |
| 107 | + |
| 108 | +tr.highlight:hover { |
| 109 | + background-color: yellow; |
| 110 | +} |
| 111 | + |
| 112 | +th.title { |
| 113 | + font-size: larger; |
| 114 | + text-align: center; |
| 115 | + vertical-align: middle; |
| 116 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/help.css |
— | — | @@ -0,0 +1,41 @@ |
| 2 | +/* ***** BEGIN LICENSE BLOCK ***** |
| 3 | + * Version: MPL 1.1 |
| 4 | + * |
| 5 | + * The contents of this file are subject to the Mozilla Public License Version |
| 6 | + * 1.1 (the "License"); you may not use this file except in compliance with |
| 7 | + * the License. You may obtain a copy of the License at |
| 8 | + * http://www.mozilla.org/MPL/ |
| 9 | + * |
| 10 | + * Software distributed under the License is distributed on an "AS IS" basis, |
| 11 | + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| 12 | + * for the specific language governing rights and limitations under the |
| 13 | + * License. |
| 14 | + * |
| 15 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 16 | + * |
| 17 | + * The Initial Developer of the Original Code is |
| 18 | + * Netscape Communications Corporation. |
| 19 | + * Portions created by the Initial Developer are Copyright (C) 1998 |
| 20 | + * the Initial Developer. All Rights Reserved. |
| 21 | + * |
| 22 | + * Contributor(s): |
| 23 | + * Gervase Markham <gerv@gerv.net> |
| 24 | + * |
| 25 | + * ***** END LICENSE BLOCK ***** */ |
| 26 | + |
| 27 | +/* Help system */ |
| 28 | +#helpDiv { |
| 29 | + border-style: solid; |
| 30 | + border-color: #F0A000; |
| 31 | + background-color: white; |
| 32 | + padding: 5px; |
| 33 | + position: absolute; |
| 34 | + z-index: 2; |
| 35 | +} |
| 36 | + |
| 37 | +#helpIframe { |
| 38 | + overflow: hidden; |
| 39 | + position: absolute; |
| 40 | + z-index: 1; |
| 41 | + display: none; |
| 42 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/bug_activity.css |
— | — | @@ -0,0 +1,19 @@ |
| 2 | +/* |
| 3 | + * Custom mediawiki skin for bugzilla.wikimedia.org |
| 4 | + */ |
| 5 | + |
| 6 | +table.bz_bugactivity { |
| 7 | + border-spacing: 1px; |
| 8 | + border-collapse: collapse; |
| 9 | +} |
| 10 | +table.bz_bugactivity th { |
| 11 | + background-color: #E0E0E0; |
| 12 | +} |
| 13 | +table.bz_bugactivity tr { |
| 14 | + border: 1px solid silver !important; |
| 15 | +} |
| 16 | +table.bz_bugactivity td { |
| 17 | + padding: 0.3em 0.3em 0.3em 0.5em; |
| 18 | + width: auto; |
| 19 | + border: 1px solid silver !important; |
| 20 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/show_multiple.css |
— | — | @@ -0,0 +1,52 @@ |
| 2 | +hr {margin: 20px auto 40px} |
| 3 | + |
| 4 | +.bz_private { color:darkred } |
| 5 | + |
| 6 | +h1 { |
| 7 | + font-size: 2em; |
| 8 | + margin-bottom: 10px; |
| 9 | +} |
| 10 | + |
| 11 | +/* bugfields is table of all fields and values */ |
| 12 | +.bugfields { |
| 13 | + font-size: small; |
| 14 | + background: #eee; |
| 15 | + padding: 5px; |
| 16 | + border: 1px solid silver; |
| 17 | + width: 100%; |
| 18 | +} |
| 19 | + |
| 20 | +.bugfields tr { |
| 21 | + vertical-align: top; |
| 22 | +} |
| 23 | + |
| 24 | +.bugfields th { |
| 25 | + width: 10em; |
| 26 | + text-align: left; |
| 27 | + font-weight: normal; |
| 28 | + line-height: 150%; |
| 29 | +} |
| 30 | + |
| 31 | +.bugfields td { |
| 32 | + font-weight: bold; |
| 33 | + line-height: 150%; |
| 34 | +} |
| 35 | + |
| 36 | +.bugfields .rightcell { |
| 37 | + padding-left: 10px; |
| 38 | +} |
| 39 | + |
| 40 | +/* set line-height to normal for nested tables of bugfields table */ |
| 41 | +.bugfields table th, .bugfields table td { |
| 42 | + line-height: 100%; |
| 43 | + width: auto; |
| 44 | +} |
| 45 | + |
| 46 | +.bugfields table.timetracking th, .bugfields table.timetracking td { |
| 47 | + width: 10em; |
| 48 | +} |
| 49 | + |
| 50 | +.error { |
| 51 | + color: red; |
| 52 | + font-weight: bold; |
| 53 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/duplicates.css |
— | — | @@ -0,0 +1,49 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * The Initial Developer of the Original Code is Everything Solved, Inc. |
| 15 | + * Portions created by the Initial Developer are Copyright (C) 2009 |
| 16 | + * the Initial Developer. All Rights Reserved. |
| 17 | + * |
| 18 | + * Contributor(s): |
| 19 | + * Max Kanat-Alexander <mkanat@bugzilla.org> |
| 20 | + */ |
| 21 | + |
| 22 | +#duplicates_table { |
| 23 | + border-collapse: collapse; |
| 24 | +} |
| 25 | + |
| 26 | +#duplicates_table .resolved { |
| 27 | + background-color: #d9d9d9; |
| 28 | + color: black; |
| 29 | +} |
| 30 | + |
| 31 | +#duplicates_table thead tr { |
| 32 | + background-color: #ccc; |
| 33 | + color: black; |
| 34 | +} |
| 35 | + |
| 36 | +#duplicates_table thead tr th { |
| 37 | + vertical-align: middle; |
| 38 | +} |
| 39 | + |
| 40 | +#duplicates_table td, #duplicates_table th { |
| 41 | + border: 1px solid black; |
| 42 | + padding: .1em .25em; |
| 43 | +} |
| 44 | + |
| 45 | +#duplicates_table tbody td { |
| 46 | + text-align: center; |
| 47 | +} |
| 48 | +#duplicates_table tbody td.short_desc { |
| 49 | + text-align: left; |
| 50 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/reports.css |
— | — | @@ -0,0 +1,89 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * The Initial Developer of the Original Code is Everything Solved, |
| 15 | + * Inc. Portions created by the Initial Developer are Copyright (C) |
| 16 | + * 2009 the Initial Developer. All Rights Reserved. |
| 17 | + * |
| 18 | + * Contributor(s): |
| 19 | + * Max Kanat-Alexander <mkanat@bugzilla.org> |
| 20 | + */ |
| 21 | + |
| 22 | +/* describecomponents.cgi */ |
| 23 | + |
| 24 | +#components_header_table { |
| 25 | + margin-bottom: 1em; |
| 26 | +} |
| 27 | + |
| 28 | +.product_container { |
| 29 | + width: 65%; |
| 30 | +} |
| 31 | + |
| 32 | +.product_name { |
| 33 | + margin: 0; |
| 34 | +} |
| 35 | + |
| 36 | +.product_desc { |
| 37 | + /* This is padding instead of margin because it looks better |
| 38 | + * with the scrollbar. */ |
| 39 | + padding: 0 2em; |
| 40 | + font-style: italic; |
| 41 | + max-height: 5em; |
| 42 | + overflow: auto; |
| 43 | +} |
| 44 | + |
| 45 | +.instructions { |
| 46 | + font-weight: bold; |
| 47 | + font-size: 105%; |
| 48 | + padding-right: 1em; |
| 49 | +} |
| 50 | + |
| 51 | +.components_header { |
| 52 | + margin: 0; |
| 53 | + font-size: 140%; |
| 54 | +} |
| 55 | + |
| 56 | +.component_table { |
| 57 | + margin-top: -1em; |
| 58 | + margin-left: 2em; |
| 59 | +} |
| 60 | + |
| 61 | +.component_table thead th { |
| 62 | + padding-right: 1em; |
| 63 | + vertical-align: bottom; |
| 64 | + text-align: left; |
| 65 | +} |
| 66 | + |
| 67 | +.component_table td { |
| 68 | + border-bottom: 1px dotted gray; |
| 69 | +} |
| 70 | + |
| 71 | +.component_table td.component_assignee, |
| 72 | +.component_table td.component_qa_contact |
| 73 | +{ |
| 74 | + border: none; |
| 75 | + padding-top: .5em; |
| 76 | +} |
| 77 | + |
| 78 | +.component_name { |
| 79 | + font-size: 115%; |
| 80 | + font-weight: bold; |
| 81 | + padding-right: 1em; |
| 82 | + vertical-align: middle; |
| 83 | + min-width: 8em; |
| 84 | +} |
| 85 | + |
| 86 | +.component_description { |
| 87 | + padding-bottom: .5em; |
| 88 | + color: #333; |
| 89 | +} |
| 90 | + |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/panel.css |
— | — | @@ -0,0 +1,37 @@ |
| 2 | +body |
| 3 | + { |
| 4 | + font-family: sans-serif; |
| 5 | + font-size: 10pt; |
| 6 | + background-color: white; |
| 7 | + } |
| 8 | + |
| 9 | +ul |
| 10 | + { |
| 11 | + padding-left: 12px; |
| 12 | + } |
| 13 | + |
| 14 | +radio |
| 15 | + { |
| 16 | + -moz-user-select: ignore; |
| 17 | + } |
| 18 | + |
| 19 | +.text-link |
| 20 | + { |
| 21 | + margin-left: 3px; |
| 22 | + } |
| 23 | + |
| 24 | +.text-link:hover |
| 25 | + { |
| 26 | + text-decoration: underline; |
| 27 | + cursor: pointer; |
| 28 | + } |
| 29 | + |
| 30 | +.descriptive-content |
| 31 | + { |
| 32 | + color: #AAAAAA; |
| 33 | + } |
| 34 | + |
| 35 | +.descriptive-content[focused=true] |
| 36 | + { |
| 37 | + color: black; |
| 38 | + } |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global.css |
— | — | @@ -0,0 +1,431 @@ |
| 2 | +/* |
| 3 | + * Custom mediawiki skin for bugzilla.wikimedia.org |
| 4 | + */ |
| 5 | + |
| 6 | +/* global (begin) */ |
| 7 | +/* global (end) */ |
| 8 | + |
| 9 | +/* header (begin) */ |
| 10 | + |
| 11 | + #message { |
| 12 | + border: 1px solid red; |
| 13 | + margin: 0.3em 0em; |
| 14 | + padding: 0.3em; |
| 15 | + color: green; |
| 16 | + } |
| 17 | + |
| 18 | + form.mini_login input.bz_login { |
| 19 | + width: 10em; |
| 20 | + } |
| 21 | + form.mini_login input.bz_password { |
| 22 | + width: 6em; |
| 23 | + } |
| 24 | + form.mini_login input.bz_remember { |
| 25 | + margin: 0; |
| 26 | + } |
| 27 | + .bz_mini_login_help { |
| 28 | + color: #777; |
| 29 | + } |
| 30 | + |
| 31 | +/* header (end) */ |
| 32 | + |
| 33 | + |
| 34 | +/* banner (end) */ |
| 35 | + |
| 36 | +/* titles (begin) */ |
| 37 | + #titles { |
| 38 | + width: 100%; |
| 39 | + background-color: #404D6C; |
| 40 | + color: #fff; |
| 41 | + -moz-border-radius-topleft: 5px; |
| 42 | + -moz-border-radius-topright: 5px; |
| 43 | + font-size: 110%; |
| 44 | + margin: 0; |
| 45 | + padding: 0.5em; |
| 46 | + vertical-align: bottom; |
| 47 | + } |
| 48 | + |
| 49 | + #titles a { |
| 50 | + color: #fff; |
| 51 | + } |
| 52 | + |
| 53 | + #titles p { |
| 54 | + margin: 0; |
| 55 | + padding: 0; |
| 56 | + } |
| 57 | + |
| 58 | + #titles #title { |
| 59 | + font-weight: bold; |
| 60 | + white-space: nowrap; |
| 61 | + } |
| 62 | + |
| 63 | + #titles #subtitle { |
| 64 | + font-weight: normal; |
| 65 | + width: 100%; |
| 66 | + text-align: center; |
| 67 | + } |
| 68 | + |
| 69 | + #titles #information { |
| 70 | + font-weight: normal; |
| 71 | + text-align: right; |
| 72 | + font-size: 90%; |
| 73 | + white-space: nowrap; |
| 74 | + } |
| 75 | + |
| 76 | +/* titles (end) */ |
| 77 | + |
| 78 | +/* footer (begin) |
| 79 | + * See also the "header" section for styles that apply |
| 80 | + * to both the header and footer. |
| 81 | + */ |
| 82 | +/* footer (end) */ |
| 83 | + |
| 84 | + |
| 85 | +/* generic (begin) */ |
| 86 | + a { |
| 87 | + color: #039; |
| 88 | + } |
| 89 | + |
| 90 | + a:visited { |
| 91 | + color: #636; |
| 92 | + } |
| 93 | + |
| 94 | + a:hover { |
| 95 | + color: #333; |
| 96 | + } |
| 97 | + |
| 98 | + a:active { |
| 99 | + color: #000; |
| 100 | + } |
| 101 | + |
| 102 | + .clickable_area { |
| 103 | + cursor: pointer; |
| 104 | + } |
| 105 | +/* generic (end) */ |
| 106 | + |
| 107 | +/* Links that control whether or not something is visible. */ |
| 108 | +a.controller { |
| 109 | + font-size: 115%; |
| 110 | +} |
| 111 | + |
| 112 | +div#docslinks { |
| 113 | + float: right; |
| 114 | + border: 1px solid black; |
| 115 | + padding: 1ex; |
| 116 | + font-size: 80%; |
| 117 | +} |
| 118 | + |
| 119 | +#docslinks h2 { |
| 120 | + margin: 0; |
| 121 | +} |
| 122 | + |
| 123 | +.bz_obsolete { |
| 124 | + text-decoration: line-through; |
| 125 | +} |
| 126 | +.bz_inactive { |
| 127 | + text-decoration: line-through; |
| 128 | +} |
| 129 | +.bz_closed, |
| 130 | +.bz_CLOSED td { |
| 131 | + text-decoration: line-through; |
| 132 | +} |
| 133 | +.bz_private { |
| 134 | + color: darkred; |
| 135 | + background: #f3eeee; |
| 136 | +} |
| 137 | +.bz_disabled { |
| 138 | + color: #a0a0a0; |
| 139 | +} |
| 140 | + |
| 141 | +/************/ |
| 142 | +/* Comments */ |
| 143 | +/************/ |
| 144 | + |
| 145 | +.bz_comment { |
| 146 | + margin-bottom: 2em; |
| 147 | +} |
| 148 | + |
| 149 | +/* The rules for these classes make international text wrap correctly, |
| 150 | + even for languages like Japanese that have no spaces. */ |
| 151 | +.bz_comment_text, .uneditable_textarea { |
| 152 | + font-family: monospace; |
| 153 | + /* Note that these must all be on separate lines or they stop |
| 154 | + working in Konqueror. */ |
| 155 | + white-space: pre-wrap; /* CSS 3 & 2.1 */ |
| 156 | + white-space: -moz-pre-wrap; /* Gecko */ |
| 157 | + white-space: -pre-wrap; /* Opera 4-6 */ |
| 158 | + white-space: -o-pre-wrap; /* Opera 7 */ |
| 159 | +} |
| 160 | + |
| 161 | +.bz_comment_text { |
| 162 | + width: 60em; |
| 163 | + font-family: monospace; |
| 164 | + white-space: pre-wrap; |
| 165 | + font-size: 115% |
| 166 | +} |
| 167 | + |
| 168 | +.bz_comment_user, .bz_comment_time, .bz_comment_number, |
| 169 | +.bz_private_checkbox, .bz_comment_actions |
| 170 | +{ |
| 171 | + margin: 0 .5em; |
| 172 | +} |
| 173 | + |
| 174 | +.bz_comment_actions, .bz_comment_number, .bz_private_checkbox { |
| 175 | + float: right; |
| 176 | +} |
| 177 | + |
| 178 | +.bz_collapse_comment { |
| 179 | + text-decoration: none; |
| 180 | +} |
| 181 | + |
| 182 | +.bz_collapse_expand_comments { |
| 183 | + padding: 0; |
| 184 | + margin: 0 0 0 1em; |
| 185 | + list-style-type: none; |
| 186 | +} |
| 187 | +.bz_collapse_expand_comments li { |
| 188 | + margin-bottom: .5em; |
| 189 | +} |
| 190 | +.bz_comment_table td{ |
| 191 | + vertical-align: top; |
| 192 | +} |
| 193 | + |
| 194 | +.bz_private_checkbox input { |
| 195 | + margin: 0; |
| 196 | + vertical-align: middle; |
| 197 | +} |
| 198 | + |
| 199 | +.bz_comment_head, .bz_first_comment_head { |
| 200 | + padding-top: .1em; |
| 201 | + padding-bottom: .1em; |
| 202 | + padding-left: .5em; |
| 203 | + background-color: #e0e0e0; |
| 204 | +} |
| 205 | + |
| 206 | +.bz_comment_user_images img { |
| 207 | + vertical-align: bottom; |
| 208 | +} |
| 209 | + |
| 210 | +.bz_comment_hilite pre { |
| 211 | + background-color: lightgreen; |
| 212 | + margin: 0; |
| 213 | + padding: 1em 0; |
| 214 | +} |
| 215 | + |
| 216 | +/** End Comments **/ |
| 217 | + |
| 218 | +.bz_default_hidden, .bz_tui_hidden, .bz_hidden_field, .bz_hidden_option { |
| 219 | + /* We have !important because we want elements with these classes to always |
| 220 | + * be hidden, even if there is some CSS that overrides it (we use these |
| 221 | + * classes inside JavaScript to hide things). */ |
| 222 | + display: none !important; |
| 223 | +} |
| 224 | + |
| 225 | +span.quote { |
| 226 | + color: #65379c; |
| 227 | + /* Make quoted text not wrap. */ |
| 228 | + white-space: pre; |
| 229 | +} |
| 230 | + |
| 231 | +table#flags th, |
| 232 | +table#flags td { |
| 233 | + vertical-align: middle; |
| 234 | + text-align: left; |
| 235 | +} |
| 236 | + |
| 237 | +.flag_select { |
| 238 | + min-width: 3em; |
| 239 | +} |
| 240 | + |
| 241 | +#error_msg { |
| 242 | + font-size: x-large; |
| 243 | +} |
| 244 | + |
| 245 | +.throw_error { |
| 246 | + background-color: #ff0000; |
| 247 | + color: black; |
| 248 | + font-size: 120%; |
| 249 | + margin: 1em; |
| 250 | + padding: 0.5em 1em; |
| 251 | +} |
| 252 | + |
| 253 | +dt { |
| 254 | + font-weight: bolder; |
| 255 | +} |
| 256 | +body > dl > dt { |
| 257 | + border-top: dotted gray thin; |
| 258 | +} |
| 259 | +dl dl > dt { |
| 260 | + border-top: none; |
| 261 | +} |
| 262 | + |
| 263 | +#admin_table th { |
| 264 | + white-space: normal !important; |
| 265 | +} |
| 266 | + |
| 267 | +/* Style of the attachment table and time tracking table */ |
| 268 | +#attachment_table { |
| 269 | + border-collapse: collapse; |
| 270 | + border: 1px solid silver !important; |
| 271 | + width: 52em; |
| 272 | +} |
| 273 | + |
| 274 | +table.bz_time_tracking_table { |
| 275 | + padding: 0.3em 0.3em 0.3em 0.5em; |
| 276 | + border-collapse: collapse; |
| 277 | + border: 1px solid silver !important; |
| 278 | + width: 52em; |
| 279 | +} |
| 280 | +#attachment_table th, .bz_attach_footer, .bz_time_tracking_table th { |
| 281 | + background-color: #E0E0E0; |
| 282 | + color: black; |
| 283 | +} |
| 284 | + |
| 285 | +#attachment_table td, .bz_time_tracking_table th, .bz_time_tracking_table td { |
| 286 | + border: 1px solid #333333; |
| 287 | +} |
| 288 | + |
| 289 | +.bz_attach_extra_info { |
| 290 | + font-size: smaller; |
| 291 | +} |
| 292 | + |
| 293 | +.bz_attach_flags, .bz_attach_footer { |
| 294 | + white-space: nowrap; |
| 295 | +} |
| 296 | + |
| 297 | +.bz_attach_view_hide { |
| 298 | + float: right; |
| 299 | + padding-left: 1em; |
| 300 | +} |
| 301 | + |
| 302 | +table.attachment_info th { |
| 303 | + text-align: right; |
| 304 | + vertical-align: top; |
| 305 | +} |
| 306 | + |
| 307 | +table.attachment_info td { |
| 308 | + text-align: left; |
| 309 | + vertical-align: top; |
| 310 | +} |
| 311 | + |
| 312 | +/* Text displayed when the attachment is not viewable by the web browser */ |
| 313 | +#noview { |
| 314 | + text-align: left; |
| 315 | + vertical-align: middle; |
| 316 | +} |
| 317 | + |
| 318 | +/* For bug fields */ |
| 319 | +.uneditable_textarea { |
| 320 | + width: 30em; |
| 321 | + font-size: medium; |
| 322 | +} |
| 323 | + |
| 324 | +div.user_match { |
| 325 | + margin-bottom: 1em; |
| 326 | +} |
| 327 | + |
| 328 | +.box { |
| 329 | + border: 1px solid black; |
| 330 | + color: black; |
| 331 | + background-color: #ffc; |
| 332 | + margin: 1em; |
| 333 | + padding: 0.5em 1em; |
| 334 | +} |
| 335 | + |
| 336 | +.collapsed { |
| 337 | + display: none; |
| 338 | +} |
| 339 | + |
| 340 | +/* Rules specific for printing */ |
| 341 | +@media print { |
| 342 | + #header, #footer { |
| 343 | + display: none; |
| 344 | + } |
| 345 | + |
| 346 | + body { |
| 347 | + background-image: none; |
| 348 | + background-color: #fff; |
| 349 | + } |
| 350 | +} |
| 351 | + |
| 352 | +.field_label { |
| 353 | + text-align: right; |
| 354 | + vertical-align: top; |
| 355 | + font-weight: bold; |
| 356 | + white-space: nowrap; |
| 357 | +} |
| 358 | + |
| 359 | +.field_value, form#Create th, form#Create td { |
| 360 | + vertical-align: top; |
| 361 | +} |
| 362 | + |
| 363 | +.calendar_button { |
| 364 | + background: transparent url("global/calendar.png") no-repeat; |
| 365 | + width: 20px; |
| 366 | + height: 20px; |
| 367 | + vertical-align: middle; |
| 368 | +} |
| 369 | +.calendar_button span { display: none } |
| 370 | +/* These classes are set by YUI. */ |
| 371 | +.yui-calcontainer { |
| 372 | + display: none; |
| 373 | + background-color: white; |
| 374 | + padding: 10px; |
| 375 | + border: 1px solid #404D6C; |
| 376 | +} |
| 377 | + |
| 378 | +.bug_urls { |
| 379 | + margin: 0 0 1em 0; |
| 380 | + padding: 0; |
| 381 | + list-style-type: none; |
| 382 | +} |
| 383 | + |
| 384 | +form#Create th { |
| 385 | + text-align: right; |
| 386 | +} |
| 387 | + |
| 388 | +form#Create .comment { |
| 389 | + vertical-align: top; |
| 390 | + overflow: auto; |
| 391 | + color: green; |
| 392 | + margin: 0 0.5em; |
| 393 | + padding: 0.3em; |
| 394 | + height: 8ex; |
| 395 | +} |
| 396 | + |
| 397 | +.image_button { |
| 398 | + background-repeat: no-repeat; |
| 399 | + background-position: center center; |
| 400 | + width: 30px; |
| 401 | + height: 20px; |
| 402 | +} |
| 403 | + |
| 404 | +#select_button { |
| 405 | + background-image: url(global/right.png); |
| 406 | +} |
| 407 | + |
| 408 | +#deselect_button { |
| 409 | + background-image: url(global/left.png); |
| 410 | +} |
| 411 | + |
| 412 | +#up_button { |
| 413 | + background-image: url(global/up.png); |
| 414 | +} |
| 415 | + |
| 416 | +#down_button { |
| 417 | + background-image: url(global/down.png); |
| 418 | +} |
| 419 | +.bz_emailprefs tr.bz_row_odd { |
| 420 | + background-color: #f0f0f0; |
| 421 | +} |
| 422 | + |
| 423 | +th.required:before { |
| 424 | + content: "* "; |
| 425 | +} |
| 426 | +th.required:before, span.required_star { |
| 427 | + color: red; |
| 428 | +} |
| 429 | +input.required, select.required, span.required_explanation { |
| 430 | + background-color: #fff7cd; |
| 431 | +} |
| 432 | + |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/vector.css |
— | — | @@ -0,0 +1,522 @@ |
| 2 | +/* |
| 3 | + * Custom mediawiki skin for bugzilla.wikimedia.org |
| 4 | + */ |
| 5 | + |
| 6 | +/* Framework */ |
| 7 | +html, |
| 8 | +body { |
| 9 | + height: 100%; |
| 10 | + margin: 0; |
| 11 | + padding: 0; |
| 12 | + font-family: sans-serif; |
| 13 | + font-size: 1em; |
| 14 | +} |
| 15 | +body { |
| 16 | + background-color: #f3f3f3; |
| 17 | + background-image: url(images/page-base.png); |
| 18 | +} |
| 19 | +/* Content */ |
| 20 | +#content-container { |
| 21 | + margin-left: 10em; |
| 22 | + padding: 1em; |
| 23 | + background-image: url(images/border.png); |
| 24 | + background-position: top left; |
| 25 | + background-repeat: repeat-y; |
| 26 | + background-color: white; |
| 27 | +} |
| 28 | +/* Head */ |
| 29 | +#page-base { |
| 30 | + height: 2.5em; |
| 31 | + background-color: white; |
| 32 | + background-image: url(images/page-fade.png); |
| 33 | + background-position: bottom left; |
| 34 | + background-repeat: repeat-x; |
| 35 | +} |
| 36 | +#head-base { |
| 37 | + margin-top: -2.5em; |
| 38 | + margin-left: 10em; |
| 39 | + height: 2.5em; |
| 40 | + background-image: url(images/border.png); |
| 41 | + background-position: bottom left; |
| 42 | + background-repeat: repeat-x; |
| 43 | +} |
| 44 | +#head { |
| 45 | + position: absolute; |
| 46 | + top: 0; |
| 47 | + right: 0; |
| 48 | + width: 100%; |
| 49 | +} |
| 50 | +#head h5 { |
| 51 | + margin: 0; |
| 52 | + padding: 0; |
| 53 | +} |
| 54 | + /* Hide empty portlets */ |
| 55 | + div.emptyPortlet { |
| 56 | + display: none; |
| 57 | + } |
| 58 | + /* Personal */ |
| 59 | + #p-personal #mini_login_container .mini_login { |
| 60 | + margin-left:-6px; |
| 61 | + margin-right:6px; |
| 62 | + margin-top:-5px; |
| 63 | + margin-bottom:-1px; |
| 64 | + } |
| 65 | + #p-personal #forgot_container .mini_forgot { |
| 66 | + margin-left:-6px; |
| 67 | + margin-right:6px; |
| 68 | + margin-top:-5px; |
| 69 | + margin-bottom:-1px; |
| 70 | + padding-left: 1.5em; |
| 71 | + } |
| 72 | + #p-personal { |
| 73 | + margin-top: 0.5em; |
| 74 | + margin-right: 1em; |
| 75 | + float: right; |
| 76 | + } |
| 77 | + #p-personal h5 { |
| 78 | + display: none; |
| 79 | + } |
| 80 | + #p-personal ul { |
| 81 | + list-style: none; |
| 82 | + margin: 0; |
| 83 | + padding: 0; |
| 84 | + } |
| 85 | + #p-personal li { |
| 86 | + line-height: 1.125em; |
| 87 | + float: left; |
| 88 | + } |
| 89 | + #p-personal li { |
| 90 | + margin-left: 0.75em; |
| 91 | + margin-top: 0.5em; |
| 92 | + font-size: 0.75em; |
| 93 | + } |
| 94 | + /* Search */ |
| 95 | + #p-search h5 { |
| 96 | + display: none; |
| 97 | + } |
| 98 | + #p-search { |
| 99 | + float: right; |
| 100 | + } |
| 101 | + #p-search { |
| 102 | + margin-right: 0.5em; |
| 103 | + margin-left: 0.5em; |
| 104 | + } |
| 105 | + #p-search form, |
| 106 | + #p-search input { |
| 107 | + margin: 0; |
| 108 | + margin-top: 0.4em; |
| 109 | + } |
| 110 | + #simpleSearch { |
| 111 | + margin-top: 0.5em; |
| 112 | + position: relative; |
| 113 | + border: solid 1px #AAAAAA; |
| 114 | + background-color: white; |
| 115 | + background-image: url(images/search-fade.png); |
| 116 | + background-position: top left; |
| 117 | + background-repeat: repeat-x; |
| 118 | + } |
| 119 | + #simpleSearch label { |
| 120 | + font-size: 0.8em; |
| 121 | + top: 0.25em; |
| 122 | + } |
| 123 | + #simpleSearch input#searchInput { |
| 124 | + margin: 0; |
| 125 | + border-width: 0; |
| 126 | + padding: 0.25em; |
| 127 | + line-height: 1em; |
| 128 | + font-size: 0.8em; |
| 129 | + width: 9em; |
| 130 | + background-color: transparent; |
| 131 | + } |
| 132 | + /* OVERRIDDEN BY COMPLIANT BROWSERS */ |
| 133 | + #simpleSearch button#searchButton { |
| 134 | + margin: 0; |
| 135 | + padding: 0; |
| 136 | + width: 1.75em; |
| 137 | + height: 1.5em; |
| 138 | + border: none; |
| 139 | + cursor: pointer; |
| 140 | + background-color: transparent; |
| 141 | + background-image: url(images/search-ltr.png); |
| 142 | + background-position: center center; |
| 143 | + background-repeat: no-repeat; |
| 144 | + } |
| 145 | + /* IGNORED BY IE6 */ |
| 146 | + #simpleSearch > button#searchButton { |
| 147 | + height: 100%; |
| 148 | + } |
| 149 | + |
| 150 | + form.mini_login input.bz_login { |
| 151 | + width: 10em; |
| 152 | + } |
| 153 | + form.mini_login input.bz_password { |
| 154 | + width: 6em; |
| 155 | + } |
| 156 | + form.mini_login input.bz_remember { |
| 157 | + margin: 0; |
| 158 | + } |
| 159 | + .bz_default_hidden { |
| 160 | + display: none !important; |
| 161 | + } |
| 162 | + |
| 163 | + |
| 164 | +/* Panel */ |
| 165 | +#panel { |
| 166 | + position: absolute; |
| 167 | + top: 160px; |
| 168 | + padding-top: 1em; |
| 169 | + width: 10em; |
| 170 | + left: 0; |
| 171 | +} |
| 172 | + #panel div.portal { |
| 173 | + padding-bottom: 1.5em; |
| 174 | + } |
| 175 | + #panel div.portal h5 { |
| 176 | + font-weight: normal; |
| 177 | + color: #444444; |
| 178 | + padding: 0.25em; |
| 179 | + padding-top: 0; |
| 180 | + padding-left: 1.75em; |
| 181 | + margin: 0.25em 0; |
| 182 | + cursor: default; |
| 183 | + border: none; |
| 184 | + font-size: 0.75em; |
| 185 | + } |
| 186 | + #panel div.portal div.body { |
| 187 | + margin: 0; |
| 188 | + padding-top: 0.5em; |
| 189 | + margin-left: 1.25em; |
| 190 | + background-image: url(images/portal-break.png); |
| 191 | + background-repeat: no-repeat; |
| 192 | + background-position: top left; |
| 193 | + } |
| 194 | + #panel div.portal div.body ul { |
| 195 | + list-style: none; |
| 196 | + list-style-image: none; |
| 197 | + list-style-type: none; |
| 198 | + padding: 0; |
| 199 | + margin: 0; |
| 200 | + } |
| 201 | + #panel div.portal div.body ul li { |
| 202 | + line-height: 1.125em; |
| 203 | + padding: 0; |
| 204 | + padding-bottom: 0.5em; |
| 205 | + margin: 0; |
| 206 | + overflow: hidden; |
| 207 | + font-size: 0.75em; |
| 208 | + } |
| 209 | + #panel div.portal div.body ul li a { |
| 210 | + color: #0645ad; |
| 211 | + } |
| 212 | + #panel div.portal div.body ul li a:visited { |
| 213 | + color: #0b0080; |
| 214 | + } |
| 215 | +/* Footer */ |
| 216 | +#footer { |
| 217 | + margin-left: 10em; |
| 218 | + margin-top: 0; |
| 219 | + padding: 0.75em; |
| 220 | + background-image: url(images/border.png); |
| 221 | + background-position: top left; |
| 222 | + background-repeat: repeat-x; |
| 223 | +} |
| 224 | +#footer ul { |
| 225 | + list-style: none; |
| 226 | + list-style-image: none; |
| 227 | + list-style-type: none; |
| 228 | + margin: 0; |
| 229 | + padding: 0; |
| 230 | +} |
| 231 | +#footer ul li { |
| 232 | + margin: 0; |
| 233 | + padding: 0; |
| 234 | + padding-top: 0.5em; |
| 235 | + padding-bottom: 0.5em; |
| 236 | + color: #333333; |
| 237 | + font-size: 0.7em; |
| 238 | +} |
| 239 | +#footer #footer-icons { |
| 240 | + float: right; |
| 241 | +} |
| 242 | +#footer #footer-places { |
| 243 | + float: left; |
| 244 | +} |
| 245 | +#footer #footer-info li { |
| 246 | + line-height: 1.4em; |
| 247 | +} |
| 248 | +#footer #footer-icons li { |
| 249 | + float: left; |
| 250 | + margin-left: 0.5em; |
| 251 | + line-height: 2em; |
| 252 | +} |
| 253 | +#footer #footer-places li { |
| 254 | + float: left; |
| 255 | + margin-right: 1em; |
| 256 | + line-height: 2em; |
| 257 | +} |
| 258 | +/* Logo */ |
| 259 | +#p-logo { |
| 260 | + position: absolute; |
| 261 | + top: -160px; |
| 262 | + left: 0; |
| 263 | + width: 10em; |
| 264 | + height: 160px; |
| 265 | +} |
| 266 | +#p-logo a { |
| 267 | + display: block; |
| 268 | + width: 10em; |
| 269 | + height: 160px; |
| 270 | + background-repeat: no-repeat; |
| 271 | + background-position: center center; |
| 272 | + text-decoration: none; |
| 273 | +} |
| 274 | + |
| 275 | + |
| 276 | +/* tabs (begin) */ |
| 277 | +div.tabbed { |
| 278 | + background-color:#F9F9F9; |
| 279 | + background-image:url(images/preferences-base.png); |
| 280 | + #border: solid #CCCCCC; |
| 281 | + #border-width: 0 1px 1px 1px; |
| 282 | + clear:both; |
| 283 | + width:100%; |
| 284 | + margin: 2.25em 0 0 0; |
| 285 | +} |
| 286 | + |
| 287 | + div.tabbody { |
| 288 | + padding: 1em 1em 1em 1em; |
| 289 | + border: solid #CCCCCC; |
| 290 | + border-width: 1px; |
| 291 | +} |
| 292 | +div.tabbody table td, div.tabbody table th, #bodyContent form table td, #bodyContent form table th { |
| 293 | + border:none !important; |
| 294 | + padding: 0.15em 0.25em; |
| 295 | + line-height: 1.75em; |
| 296 | +} |
| 297 | +table.tabs { |
| 298 | + position:absolute; |
| 299 | + width:auto; |
| 300 | + background-image:url(images/preferences-break.png); |
| 301 | + background-position:left bottom; |
| 302 | + background-repeat:no-repeat; |
| 303 | + margin: -2.25em 0 0 0; |
| 304 | + padding-left: 1px; |
| 305 | +} |
| 306 | +.tabs tbody { |
| 307 | + background-image:url(images/preferences-fade.png); |
| 308 | + background-position:left bottom; |
| 309 | + background-repeat:repeat-x; |
| 310 | +} |
| 311 | + |
| 312 | +.tabs td { |
| 313 | + width: auto; |
| 314 | + line-height:1.5em; |
| 315 | + background-image:url(images/preferences-break.png); |
| 316 | + background-color: white; |
| 317 | + background-position:right bottom; |
| 318 | + background-repeat:no-repeat; |
| 319 | + border: solid #CCCCCC; |
| 320 | + border-width: 0 0 1px 0; |
| 321 | + text-align: center; |
| 322 | + margin:0; |
| 323 | + padding:0 .75em 3px .75em; |
| 324 | + white-space:nowrap; |
| 325 | + font-size: 0.9em; |
| 326 | +} |
| 327 | +.tabs td a { |
| 328 | + background-image:none; |
| 329 | + color:#0645AD; |
| 330 | + display:inline-block; |
| 331 | + position:relative; |
| 332 | + line-height: 2.25em; |
| 333 | +} |
| 334 | +.tabs td.selected { |
| 335 | + background-color:transparent; |
| 336 | + color:#333333; |
| 337 | + border-width: 0; |
| 338 | + text-decoration:none; |
| 339 | +} |
| 340 | +.tabs td.spacer { |
| 341 | + display: none; |
| 342 | +} |
| 343 | +/* tabs (end) */ |
| 344 | + |
| 345 | +/* Content */ |
| 346 | +#content-container { |
| 347 | + line-height: 1.5em; |
| 348 | +} |
| 349 | +#bodyContent { |
| 350 | + font-size: 0.8em; |
| 351 | + position: relative; |
| 352 | + width: 100%; |
| 353 | + line-height: 1.5em; |
| 354 | +} |
| 355 | +#bodyContent table { |
| 356 | + font-size: 100%; |
| 357 | + border: none; |
| 358 | +} |
| 359 | +#bodyContent td, #bodyContent th { |
| 360 | + border: none; |
| 361 | +} |
| 362 | +/* Links */ |
| 363 | +a { |
| 364 | + text-decoration: none; |
| 365 | + color: #0645ad; |
| 366 | + background: none; |
| 367 | +} |
| 368 | +a:visited { |
| 369 | + color: #0b0080; |
| 370 | +} |
| 371 | +a:active { |
| 372 | + color: #faa700; |
| 373 | +} |
| 374 | +a:hover { |
| 375 | + text-decoration: underline; |
| 376 | +} |
| 377 | +a.stub { |
| 378 | + color: #772233; |
| 379 | +} |
| 380 | +a.new, |
| 381 | +#p-personal a.new { |
| 382 | + color: #ba0000; |
| 383 | +} |
| 384 | +a.new:visited, |
| 385 | +#p-personal a.new:visited { |
| 386 | + color: #a55858; |
| 387 | +} |
| 388 | +/* Inline Elements */ |
| 389 | +img { |
| 390 | + border: none; |
| 391 | + vertical-align: middle; |
| 392 | +} |
| 393 | +hr { |
| 394 | + height: 1px; |
| 395 | + color: #aaa; |
| 396 | + background-color: #aaa; |
| 397 | + border: 0; |
| 398 | + margin: .2em 0 .2em 0; |
| 399 | +} |
| 400 | +/* Structural Elements */ |
| 401 | +p { |
| 402 | + margin: .4em 0 .5em 0; |
| 403 | + line-height: 1.5em; |
| 404 | +} |
| 405 | +abbr, |
| 406 | +acronym { |
| 407 | + border-bottom: 1px dotted black; |
| 408 | + color: black; |
| 409 | + background: none; |
| 410 | + cursor: help; |
| 411 | +} |
| 412 | +q { |
| 413 | + font-family: Times, "Times New Roman", serif; |
| 414 | + font-style: italic; |
| 415 | +} |
| 416 | +code { |
| 417 | + background-color: #f9f9f9; |
| 418 | +} |
| 419 | +pre { |
| 420 | + padding: 1em; |
| 421 | + border: 1px dashed #2f6fab; |
| 422 | + color: black; |
| 423 | + background-color: #f9f9f9; |
| 424 | + line-height: 1.1em; |
| 425 | +} |
| 426 | +tbody.file pre { |
| 427 | + padding: 0; |
| 428 | + border: 0; |
| 429 | + background: transparent; |
| 430 | + } |
| 431 | +ul { |
| 432 | + line-height: 1.5em; |
| 433 | + list-style-type: square; |
| 434 | + margin: .3em 0 0 1.5em; |
| 435 | + padding: 0; |
| 436 | + list-style-image: url(images/bullet-icon.png); |
| 437 | +} |
| 438 | +ol { |
| 439 | + line-height: 1.5em; |
| 440 | + margin: .3em 0 0 3.2em; |
| 441 | + padding: 0; |
| 442 | + list-style-image: none; |
| 443 | +} |
| 444 | +li { |
| 445 | + margin-bottom: .1em; |
| 446 | +} |
| 447 | +dt { |
| 448 | + font-weight: bold; |
| 449 | + margin-bottom: .1em; |
| 450 | +} |
| 451 | +dl { |
| 452 | + margin-top: .2em; |
| 453 | + margin-bottom: .5em; |
| 454 | +} |
| 455 | +dd { |
| 456 | + line-height: 1.5em; |
| 457 | + margin-left: 2em; |
| 458 | + margin-bottom: .1em; |
| 459 | +} |
| 460 | +#content-container a.external, |
| 461 | +#content-container a[href ^="gopher://"] { |
| 462 | + background: url(images/external-link-ltr-icon.png) center right no-repeat; |
| 463 | + padding: 0 13px 0 0; |
| 464 | +} |
| 465 | +#content-container a[href ^="https://"], |
| 466 | +.link-https { |
| 467 | + background: url(images/lock-icon.png) center right no-repeat; |
| 468 | + padding: 0 18px 0 0; |
| 469 | +} |
| 470 | +#content-container a[href ^="mailto:"], |
| 471 | +.link-mailto { |
| 472 | + background: url(images/mail-icon.png) center right no-repeat; |
| 473 | + padding: 0 18px 0 0; |
| 474 | +} |
| 475 | +#content-container a[href ^="news://"] { |
| 476 | + background: url(images/news-icon.png) center right no-repeat; |
| 477 | + padding: 0 18px 0 0; |
| 478 | +} |
| 479 | +#content-container a[href ^="ftp://"], |
| 480 | +.link-ftp { |
| 481 | + background: url(images/file-icon.png) center right no-repeat; |
| 482 | + padding: 0 18px 0 0; |
| 483 | +} |
| 484 | +#content-container a[href ^="irc://"], |
| 485 | +#content-container a.extiw[href ^="irc://"], |
| 486 | +.link-irc { |
| 487 | + background: url(images/talk-icon.png) center right no-repeat; |
| 488 | + padding: 0 18px 0 0; |
| 489 | +} |
| 490 | +#content-container a.external[href $=".ogg"], #content-container a.external[href $=".OGG"], |
| 491 | +#content-container a.external[href $=".mid"], #content-container a.external[href $=".MID"], |
| 492 | +#content-container a.external[href $=".midi"], #content-container a.external[href $=".MIDI"], |
| 493 | +#content-container a.external[href $=".mp3"], #content-container a.external[href $=".MP3"], |
| 494 | +#content-container a.external[href $=".wav"], #content-container a.external[href $=".WAV"], |
| 495 | +#content-container a.external[href $=".wma"], #content-container a.external[href $=".WMA"], |
| 496 | +.link-audio { |
| 497 | + background: url("images/audio-icon.png") center right no-repeat; |
| 498 | + padding: 0 18px 0 0; |
| 499 | +} |
| 500 | +#content-container a.external[href $=".ogm"], #content-container a.external[href $=".OGM"], |
| 501 | +#content-container a.external[href $=".avi"], #content-container a.external[href $=".AVI"], |
| 502 | +#content-container a.external[href $=".mpeg"], #content-container a.external[href $=".MPEG"], |
| 503 | +#content-container a.external[href $=".mpg"], #content-container a.external[href $=".MPG"], |
| 504 | +.link-video { |
| 505 | + background: url("images/video-icon.png") center right no-repeat; |
| 506 | + padding: 0 18px 0 0; |
| 507 | +} |
| 508 | +#content-container a.external[href $=".pdf"], #content-container a.external[href $=".PDF"], |
| 509 | +#content-container a.external[href *=".pdf#"], #content-container a.external[href *=".PDF#"], |
| 510 | +#content-container a.external[href *=".pdf?"], #content-container a.external[href *=".PDF?"], |
| 511 | +.link-document { |
| 512 | + background: url("images/document-icon.png") center right no-repeat; |
| 513 | + padding: 0 18px 0 0; |
| 514 | +} |
| 515 | +#content-container a.external { |
| 516 | + color: #36b; |
| 517 | +} |
| 518 | +/* Icon for Usernames */ |
| 519 | +.user-link { |
| 520 | + background: url(images/user-icon.png) left top no-repeat; |
| 521 | + padding-left: 15px !important; |
| 522 | + text-transform: none; |
| 523 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/voting.css |
— | — | @@ -0,0 +1,24 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Gavin Shelley <bugzilla@chimpychompy.org> |
| 15 | + */ |
| 16 | + |
| 17 | +/* Highlight the row for the bug being voted on */ |
| 18 | +tr.bz_bug_being_voted_on { |
| 19 | + background-color: #e2e2e2; |
| 20 | +} |
| 21 | + |
| 22 | +tr.bz_bug_being_voted_on td { |
| 23 | + border-style: solid none solid none; |
| 24 | + border-width: thin; |
| 25 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/editusers.css |
— | — | @@ -0,0 +1,71 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Marc Schumann <wurblzap@gmail.com> |
| 15 | + */ |
| 16 | + |
| 17 | +table.main { |
| 18 | + border-spacing: 1em; |
| 19 | +} |
| 20 | +table.main tr { |
| 21 | + vertical-align: top; |
| 22 | + border-top: solid thin black; |
| 23 | +} |
| 24 | +table.main th { |
| 25 | + text-align: right; |
| 26 | + white-space: nowrap; |
| 27 | +} |
| 28 | +table.main th, |
| 29 | +table.main td { |
| 30 | + padding: 0; |
| 31 | +} |
| 32 | +table.main ul { |
| 33 | + list-style-type: none; |
| 34 | + padding-left: 0 |
| 35 | +} |
| 36 | + |
| 37 | +table.groups { |
| 38 | + border-spacing: 1px; |
| 39 | +} |
| 40 | +table.groups tr.indirect { |
| 41 | + background-color: #cccccc; |
| 42 | +} |
| 43 | +table.groups th { |
| 44 | + text-align: left; |
| 45 | + padding: 0 0 0 1ex; |
| 46 | +} |
| 47 | +table.groups td { |
| 48 | + padding: 2px; |
| 49 | +} |
| 50 | +table.groups td.checkbox { |
| 51 | + text-align: center; |
| 52 | + white-space: nowrap; |
| 53 | +} |
| 54 | + |
| 55 | +table#user_responsibilities th { |
| 56 | + text-align: center; |
| 57 | + padding: 0 1em 1em; |
| 58 | +} |
| 59 | + |
| 60 | +table#user_responsibilities th.product { |
| 61 | + text-align: left; |
| 62 | + padding: 1em 0 0; |
| 63 | +} |
| 64 | + |
| 65 | +table#user_responsibilities td.center { |
| 66 | + text-align: center; |
| 67 | +} |
| 68 | + |
| 69 | +.missing { |
| 70 | + color: red; |
| 71 | + border-color: inherit; |
| 72 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/index.css |
— | — | @@ -0,0 +1,133 @@ |
| 2 | + /* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Vitaly Harisov <vitaly@rathedg.com> |
| 15 | + * Guy Pyrzak <guy.pyrzak@gmail.com> |
| 16 | + */ |
| 17 | + |
| 18 | +/* index page (begin) */ |
| 19 | + |
| 20 | + #page-index |
| 21 | + { |
| 22 | + padding: 0.2em 0.2em 0.15em 0.2em; |
| 23 | + } |
| 24 | + |
| 25 | + /* By default these contain nothing, but these CSS rules make things |
| 26 | + easier on customizers. */ |
| 27 | + .intro, .outro { |
| 28 | + text-align: center; |
| 29 | + width: 50em; |
| 30 | + } |
| 31 | + |
| 32 | + /* Hide from NN4 */ |
| 33 | + |
| 34 | + #new_release |
| 35 | + { |
| 36 | + border: 2px solid red; |
| 37 | + padding: 0.5em 1em; |
| 38 | + margin: 1em; |
| 39 | + font-weight: bold; |
| 40 | + } |
| 41 | + |
| 42 | + #new_release .notice |
| 43 | + { |
| 44 | + font-size: 80%; |
| 45 | + font-weight: normal; |
| 46 | + } |
| 47 | + |
| 48 | + #welcome-admin a |
| 49 | + { |
| 50 | + font-weight: bold; |
| 51 | + } |
| 52 | + |
| 53 | + .bz_common_actions { |
| 54 | + display: block; |
| 55 | + height: 190px; |
| 56 | + width: 195px; |
| 57 | + float: left; |
| 58 | + margin: 0 3ex 3em 0; |
| 59 | + text-align: center; |
| 60 | + } |
| 61 | + .bz_common_actions span { |
| 62 | + position: relative; |
| 63 | + top: 95%; |
| 64 | + font-weight: bold; |
| 65 | + } |
| 66 | + |
| 67 | + .bz_common_actions, |
| 68 | + .bz_common_actions:visited, |
| 69 | + .bz_common_actions:hover |
| 70 | + { |
| 71 | + text-decoration: none; |
| 72 | + } |
| 73 | + |
| 74 | + #enter_bug { background: url(index/bug.gif) no-repeat; } |
| 75 | + #query { background: url(index/search.gif) no-repeat; } |
| 76 | + #account { background: url(index/account.gif) no-repeat; } |
| 77 | + |
| 78 | + #quicksearchForm |
| 79 | + { |
| 80 | + clear: both; |
| 81 | + text-align: center; |
| 82 | + margin-bottom: 2em; |
| 83 | + } |
| 84 | + |
| 85 | + #quicksearchForm #quicksearch_main |
| 86 | + { |
| 87 | + width: 25em; |
| 88 | + } |
| 89 | + |
| 90 | + #quicksearchForm |
| 91 | + { |
| 92 | + margin: 0; |
| 93 | + padding: 0; |
| 94 | + } |
| 95 | + |
| 96 | + #page-index table{ |
| 97 | + border-collapse: collapse; |
| 98 | + } |
| 99 | + |
| 100 | + #welcome |
| 101 | + { |
| 102 | + font-size: x-large; |
| 103 | + font-weight: bold; |
| 104 | + text-align: center; |
| 105 | + margin: 0 0 0.8em 0; |
| 106 | + padding: 0; |
| 107 | + } |
| 108 | + |
| 109 | + ul.additional_links |
| 110 | + { |
| 111 | + list-style: none; |
| 112 | + margin: 0; |
| 113 | + padding: 0; |
| 114 | + } |
| 115 | + |
| 116 | + ul#quicksearch_links{ |
| 117 | + margin-bottom: 1em; |
| 118 | + } |
| 119 | + |
| 120 | + ul.additional_links li |
| 121 | + { |
| 122 | + display: inline; |
| 123 | + } |
| 124 | + |
| 125 | + ul.additional_links li.bz_default_hidden |
| 126 | + { |
| 127 | + display: none; |
| 128 | + } |
| 129 | + |
| 130 | + input.quicksearch_help_text |
| 131 | + { |
| 132 | + color: #ccc; |
| 133 | + } |
| 134 | +/* index page (end) */ |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/summarize-time.css |
— | — | @@ -0,0 +1,46 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Christian Reis <kiko@async.com.br> |
| 15 | + */ |
| 16 | + |
| 17 | +td { vertical-align: top } |
| 18 | + |
| 19 | +table.zeroitems, table.realitems { |
| 20 | + margin-left: 2.0em; |
| 21 | + margin-top: 2px; |
| 22 | + border: 1px solid black; |
| 23 | + border: 1px solid black; |
| 24 | +} |
| 25 | + |
| 26 | +tr.section_total { |
| 27 | + background: #000000; |
| 28 | + color: #ffffff; |
| 29 | +} |
| 30 | + |
| 31 | +td.subtotal { |
| 32 | + background: #B0C0D9; |
| 33 | +} |
| 34 | + |
| 35 | +.zeroitems .bug_header { background: #d0e0f0 } |
| 36 | +.zeroitems .bug_header2 { background: #f9f9f9 } |
| 37 | + |
| 38 | +/* the fixed headers -- .number uses bug_header so hack it here */ |
| 39 | +.number .bug_header, .number .bug_header2 { background: #d0e0f0 } |
| 40 | +.owner_header { background: #d0e0f0 } |
| 41 | + |
| 42 | + |
| 43 | +/* the details headers */ |
| 44 | +.number .owner_header, .owner .bug_header { background: #ffffff } |
| 45 | +.number .owner_header2, .owner .bug_header2 { background: #EFEFEF } |
| 46 | + |
| 47 | + |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/IE-fixes.css |
— | — | @@ -0,0 +1,42 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Marc Schumann <wurblzap@gmail.com> |
| 15 | + */ |
| 16 | + |
| 17 | +.bz_comment_text, .uneditable_textarea { |
| 18 | + white-space: pre; |
| 19 | + word-wrap: break-word; |
| 20 | +} |
| 21 | + |
| 22 | +.component_table { |
| 23 | + margin-top: .5em; |
| 24 | +} |
| 25 | + |
| 26 | +#footer #useful-links li { |
| 27 | + padding-bottom: 0.8ex; |
| 28 | +} |
| 29 | + |
| 30 | +#footer .label { |
| 31 | + display: block; |
| 32 | + float: left; |
| 33 | + width: 8.2em; |
| 34 | + padding-bottom: 0.1ex; |
| 35 | +} |
| 36 | + |
| 37 | +#footer #links-actions .label { |
| 38 | + padding-top: 0.35em; |
| 39 | +} |
| 40 | + |
| 41 | +#footer .links { |
| 42 | + display: inline; |
| 43 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/buglist.css |
— | — | @@ -0,0 +1,66 @@ |
| 2 | +/* |
| 3 | + * Custom mediawiki skin for bugzilla.wikimedia.org |
| 4 | + */ |
| 5 | + |
| 6 | +table.bz_buglist td { |
| 7 | + padding: 0.5em 0.25em; |
| 8 | +} |
| 9 | +tr.bz_bugitem:hover { |
| 10 | + background-color: #f0f0f0; |
| 11 | +} |
| 12 | +/* Must go first because of issue with BugZilla wrongly assuming case sensitivity in CSS classes */ |
| 13 | +.bz_normal { |
| 14 | + color:#BB7700; |
| 15 | +} |
| 16 | +/* Otherwise, in order of severity */ |
| 17 | +.bz_enhancement { |
| 18 | + color:#106581; |
| 19 | +} |
| 20 | +.bz_trivial { |
| 21 | + color:#009966; |
| 22 | +} |
| 23 | +.bz_minor { |
| 24 | + color:#669900; |
| 25 | +} |
| 26 | +.bz_major { |
| 27 | + color:#D30000; |
| 28 | +} |
| 29 | +.bz_critical { |
| 30 | + color:#CC0000; |
| 31 | +} |
| 32 | +.bz_blocker { |
| 33 | + color:#AA0000; |
| 34 | + font-weight:bold; |
| 35 | +} |
| 36 | +tr.bz_secure_mode_implied td.first-child { |
| 37 | +} |
| 38 | + |
| 39 | +tr.bz_secure_mode_manual td.first-child { |
| 40 | +} |
| 41 | + |
| 42 | +td.bz_estimated_time_column, |
| 43 | +td.bz_remaining_time_column, |
| 44 | +td.bz_actual_time_column, |
| 45 | +td.bz_percentage_complete_column { |
| 46 | + text-align: right; |
| 47 | +} |
| 48 | + |
| 49 | +td.bz_total_label { |
| 50 | + font-weight: bold; |
| 51 | +} |
| 52 | + |
| 53 | +td.bz_total { |
| 54 | + border-top-style: solid; |
| 55 | + border-top-color: #929bb1; |
| 56 | + border-top-width: 3px; |
| 57 | + text-align: right; |
| 58 | +} |
| 59 | + |
| 60 | +#commit, #action { |
| 61 | + margin-top: .25em; |
| 62 | +} |
| 63 | + |
| 64 | +.bz_query_explain { |
| 65 | + text-align: left; |
| 66 | +} |
| 67 | + |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/body-back.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/body-back.gif |
___________________________________________________________________ |
Added: svn:mime-type |
1 | 68 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/right.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/right.png |
___________________________________________________________________ |
Added: svn:mime-type |
2 | 69 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/up.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/up.png |
___________________________________________________________________ |
Added: svn:mime-type |
3 | 70 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/down.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/down.png |
___________________________________________________________________ |
Added: svn:mime-type |
4 | 71 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/header.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/header.png |
___________________________________________________________________ |
Added: svn:mime-type |
5 | 72 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/calendar.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/calendar.png |
___________________________________________________________________ |
Added: svn:mime-type |
6 | 73 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/left.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/global/left.png |
___________________________________________________________________ |
Added: svn:mime-type |
7 | 74 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/dependency-tree.css |
— | — | @@ -0,0 +1,94 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * The Initial Developer of the Original Code is Netscape |
| 15 | + * Communications |
| 16 | + * Corporation. Portions created by Netscape are |
| 17 | + * Copyright (C) 1998 Netscape Communications Corporation. All |
| 18 | + * Rights Reserved. |
| 19 | + * |
| 20 | + * Contributor(s): Christian Reis <kiko@async.com.br> |
| 21 | + * Andr� Batosti <batosti@async.com.br> |
| 22 | + */ |
| 23 | + |
| 24 | +ul.tree { |
| 25 | + padding-left: 0em; |
| 26 | + margin-left: 1em; |
| 27 | + display: block; |
| 28 | +} |
| 29 | + |
| 30 | +ul.tree ul { |
| 31 | + padding-top: 3px; |
| 32 | + display: block; |
| 33 | +} |
| 34 | + |
| 35 | +ul.tree li { |
| 36 | + /* see http://www.kryogenix.org/code/browser/aqlists/ for idea */ |
| 37 | + padding-top: 3px; |
| 38 | + text-indent: -1.2em; |
| 39 | + padding-left: 0.5em; |
| 40 | + padding-bottom: 3px; |
| 41 | + list-style-type: none; |
| 42 | + background: url("dependency-tree/bug-item.png") no-repeat; |
| 43 | +} |
| 44 | + |
| 45 | +ul.tree li a.b { |
| 46 | + padding-left: 30px; |
| 47 | + margin-right: -14px; |
| 48 | + text-decoration: none; |
| 49 | +} |
| 50 | + |
| 51 | +ul.tree li a.b_open { |
| 52 | + background: url("dependency-tree/tree-open.png") center no-repeat; |
| 53 | + cursor: pointer; |
| 54 | +} |
| 55 | + |
| 56 | +ul.tree li a.b_closed { |
| 57 | + background: url("dependency-tree/tree-closed.png") center no-repeat; |
| 58 | + cursor: pointer; |
| 59 | +} |
| 60 | + |
| 61 | +ul.tree a.tree_link img { |
| 62 | + border: 0; |
| 63 | +} |
| 64 | + |
| 65 | +.summ_info { |
| 66 | + /* change to inline if you would like to see the full bug details |
| 67 | + * displayed in the list */ |
| 68 | + display: none; |
| 69 | + font-size: 75%; |
| 70 | +} |
| 71 | + |
| 72 | +.hint { |
| 73 | + font-size: 90%; |
| 74 | + margin: 0.2em; |
| 75 | + padding: 0.1em; |
| 76 | +} |
| 77 | + |
| 78 | +.hint h3, .hint ul { |
| 79 | + margin-top: 0.1em; |
| 80 | + margin-bottom: 0.1em; |
| 81 | +} |
| 82 | + |
| 83 | +.summ A, .summ_deep A { |
| 84 | + text-decoration: none; |
| 85 | + color: darkblue; |
| 86 | +} |
| 87 | + |
| 88 | +.summ_deep { |
| 89 | +} |
| 90 | + |
| 91 | +.summ_h A { |
| 92 | + background-color: #ffffaa; |
| 93 | + color: #333; |
| 94 | + font-weight: bold; |
| 95 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/create_attachment.css |
— | — | @@ -0,0 +1,145 @@ |
| 2 | + /* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + * |
| 14 | + * Contributor(s): Myk Melez <myk@mozilla.org> |
| 15 | + * Joel Peshkin <bugreport@peshkin.net> |
| 16 | + * Erik Stambaugh <erik@dasbistro.com> |
| 17 | + * Marc Schumann <wurblzap@gmail.com> |
| 18 | + */ |
| 19 | + |
| 20 | +table.attachment_entry th { |
| 21 | + text-align: right; |
| 22 | + vertical-align: baseline; |
| 23 | + white-space: nowrap; |
| 24 | +} |
| 25 | + |
| 26 | +table.attachment_entry td { |
| 27 | + text-align: left; |
| 28 | + vertical-align: baseline; |
| 29 | + padding-bottom: 5px; |
| 30 | +} |
| 31 | + |
| 32 | +table#flags th, |
| 33 | +table#flags td { |
| 34 | + text-align: left; |
| 35 | + vertical-align: baseline; |
| 36 | + font-size: small; |
| 37 | +} |
| 38 | + |
| 39 | +/* Rules used to view patches in diff mode. */ |
| 40 | + |
| 41 | +.file_head { |
| 42 | + font-weight: bold; |
| 43 | + font-size: 1em; |
| 44 | + background-color: #c3c3c3; |
| 45 | + border: 1px solid black; |
| 46 | +} |
| 47 | + |
| 48 | +.file_head a { |
| 49 | + text-decoration: none; |
| 50 | + font-family: monospace; |
| 51 | + font-size: 1.1em; |
| 52 | +} |
| 53 | + |
| 54 | +.file_collapse { |
| 55 | + display: none; |
| 56 | +} |
| 57 | + |
| 58 | +.section_head { |
| 59 | + background-color: #f0f0f0; |
| 60 | + border: 1px solid black; |
| 61 | + text-align: left; |
| 62 | +} |
| 63 | + |
| 64 | +table.file_table { |
| 65 | + table-layout: fixed; |
| 66 | + width: 100%; |
| 67 | + empty-cells: show; |
| 68 | + border-spacing: 0px; |
| 69 | + border-collapse: collapse; |
| 70 | + /* draw border below last open context section in listing */ |
| 71 | + border-bottom: 1px solid black; |
| 72 | +} |
| 73 | + |
| 74 | +tbody.file pre { |
| 75 | + display: inline; |
| 76 | + white-space: pre-wrap; /* CSS 3 & CSS 2.1 */ |
| 77 | + white-space: -moz-pre-wrap; /* Gecko < 1.9.1 */ |
| 78 | + white-space: -o-pre-wrap; /* Opera 7 */ |
| 79 | + font-size: 0.9em; |
| 80 | +} |
| 81 | + |
| 82 | +tbody.file pre:empty { |
| 83 | + display: block; |
| 84 | +} |
| 85 | + |
| 86 | +.changed { |
| 87 | + background-color: lightblue; |
| 88 | +} |
| 89 | + |
| 90 | +.added { |
| 91 | + background-color: lightgreen; |
| 92 | +} |
| 93 | + |
| 94 | +.removed { |
| 95 | + background-color: #FFCC99; |
| 96 | +} |
| 97 | + |
| 98 | +.num { |
| 99 | + background-color: #ffe9ae; |
| 100 | + text-align:right; |
| 101 | + padding: 0 0.3em; |
| 102 | + width: 3em; |
| 103 | +} |
| 104 | + |
| 105 | +.warning { |
| 106 | + color: red |
| 107 | +} |
| 108 | + |
| 109 | +table.attachment_info th { |
| 110 | + text-align: right; |
| 111 | + vertical-align: top; |
| 112 | +} |
| 113 | + |
| 114 | +table.attachment_info td { |
| 115 | + text-align: left; |
| 116 | + vertical-align: top; |
| 117 | +} |
| 118 | + |
| 119 | +/* Text displayed when the attachment is not viewable by the web browser */ |
| 120 | +#noview { |
| 121 | + text-align: left; |
| 122 | + vertical-align: middle; |
| 123 | +} |
| 124 | + |
| 125 | +#attachment_attributes { |
| 126 | + width: 25%; |
| 127 | +} |
| 128 | + |
| 129 | +#attachment_attributes div { |
| 130 | + padding-bottom: 0.4em; |
| 131 | +} |
| 132 | + |
| 133 | +#attachment_attributes label, |
| 134 | +#attachment_attributes span.label, |
| 135 | +#attachment_actions span.label |
| 136 | +{ |
| 137 | + font-weight: bold; |
| 138 | +} |
| 139 | + |
| 140 | +#attachment_attributes .block { |
| 141 | + display: block; |
| 142 | +} |
| 143 | + |
| 144 | +#attachment_attributes table#flags { |
| 145 | + padding-top: 1em; |
| 146 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/page.css |
— | — | @@ -0,0 +1,70 @@ |
| 2 | +/* The contents of this file are subject to the Mozilla Public |
| 3 | + * License Version 1.1 (the "License"); you may not use this file |
| 4 | + * except in compliance with the License. You may obtain a copy of |
| 5 | + * the License at http://www.mozilla.org/MPL/ |
| 6 | + * |
| 7 | + * Software distributed under the License is distributed on an "AS |
| 8 | + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + * implied. See the License for the specific language governing |
| 10 | + * rights and limitations under the License. |
| 11 | + * |
| 12 | + * The Initial Developer of the Original Code is Everything Solved. |
| 13 | + * Portions created by Everything Solved are Copyright (C) 2006 |
| 14 | + * Everything Solved. All Rights Reserved. |
| 15 | + * |
| 16 | + * The Original Code is the Bugzilla Bug Tracking System. |
| 17 | + * |
| 18 | + * Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> |
| 19 | + */ |
| 20 | + |
| 21 | +/* This CSS is used by various informational pages in the |
| 22 | + template/en/default/pages/ directory. */ |
| 23 | + |
| 24 | +#bugzilla-body { |
| 25 | + padding: 0 1em; |
| 26 | +} |
| 27 | + |
| 28 | +#bugzilla-body > * { |
| 29 | + /* People have an easier time reading narrower columns of text. */ |
| 30 | + max-width: 45em; |
| 31 | +} |
| 32 | + |
| 33 | +/*****************/ |
| 34 | +/* Release Notes */ |
| 35 | +/*****************/ |
| 36 | + |
| 37 | +.req_new { |
| 38 | + color: red; |
| 39 | +} |
| 40 | + |
| 41 | +.req_table { |
| 42 | + border-collapse: collapse; |
| 43 | +} |
| 44 | + |
| 45 | +.req_table td, .req_table th { |
| 46 | + border: 1px solid black; |
| 47 | + padding: .25em; |
| 48 | +} |
| 49 | + |
| 50 | +/********************/ |
| 51 | +/* QuickSearch Help */ |
| 52 | +/********************/ |
| 53 | + |
| 54 | +.qs_help li { |
| 55 | + margin-top: 1ex; |
| 56 | +} |
| 57 | + |
| 58 | +.qs_fields th { |
| 59 | + padding: 0 .25em; |
| 60 | +} |
| 61 | +.qs_fields th.field_nickname { |
| 62 | + text-align: left; |
| 63 | +} |
| 64 | +.qs_fields td { |
| 65 | + padding: .25em; |
| 66 | + border-top: 1px solid gray; |
| 67 | +} |
| 68 | +.qs_fields .field_name { |
| 69 | + width: 10em; |
| 70 | +} |
| 71 | + |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/show_bug.css |
— | — | @@ -0,0 +1,117 @@ |
| 2 | +/* |
| 3 | + * Custom mediawiki skin for bugzilla.wikimedia.org |
| 4 | + */ |
| 5 | + |
| 6 | +.bz_alias_short_desc_container { |
| 7 | + margin: 8px 0; |
| 8 | + padding: 0.2em 0.2em 0.3em 0.5em; |
| 9 | + background-color: #E0E0E0; |
| 10 | + border-collapse: collapse; |
| 11 | + border: 1px solid silver !important; |
| 12 | + font-weight: bold; |
| 13 | +} |
| 14 | + |
| 15 | +.bz_bug .edit_form { |
| 16 | + width: 100%; |
| 17 | +} |
| 18 | +.bz_bug .edit_form table { |
| 19 | + width: 100%; |
| 20 | +} |
| 21 | +.bz_bug .edit_form .text_input { |
| 22 | + width: 100%; |
| 23 | + min-width: 25em; |
| 24 | +} |
| 25 | +.bz_bug #alias { |
| 26 | + min-width: 0; |
| 27 | + width: 10em; |
| 28 | +} |
| 29 | + |
| 30 | +.flags_label { |
| 31 | + text-align: left; |
| 32 | +} |
| 33 | +table#flags { |
| 34 | + width: auto; |
| 35 | +} |
| 36 | + |
| 37 | +.bz_column_spacer { |
| 38 | + width: 0.5em; |
| 39 | +} |
| 40 | + |
| 41 | +.related_actions { |
| 42 | + font-size: 0.85em; |
| 43 | + float: right; |
| 44 | + list-style-type: none; |
| 45 | + white-space: nowrap; |
| 46 | + margin: 0; |
| 47 | + padding: 0; |
| 48 | +} |
| 49 | + |
| 50 | +.related_actions li { |
| 51 | + display: inline; |
| 52 | +} |
| 53 | + |
| 54 | +.bz_show_bug_column { |
| 55 | + vertical-align: top; |
| 56 | +} |
| 57 | + |
| 58 | +.bz_section_spacer { |
| 59 | + height: 1em; |
| 60 | +} |
| 61 | + |
| 62 | +#duplicate_settings, #votes_container { |
| 63 | + white-space: nowrap; |
| 64 | + |
| 65 | +} |
| 66 | + |
| 67 | +#bz_big_form_parts td { |
| 68 | + vertical-align: top; |
| 69 | +} |
| 70 | + |
| 71 | +.bz_group_visibility_section { |
| 72 | + margin-left: 1em; |
| 73 | +} |
| 74 | + |
| 75 | +.bz_group_visibility_section .instructions { |
| 76 | + font-style: italic; |
| 77 | +} |
| 78 | + |
| 79 | +#bz_restrict_group_visibility_help .instructions { |
| 80 | + margin-top: 0; |
| 81 | +} |
| 82 | + |
| 83 | +#bz_enable_role_visibility_help { |
| 84 | + margin-top: 1em; |
| 85 | +} |
| 86 | + |
| 87 | +.bz_time_tracking_table { |
| 88 | + border-collapse: collapse; |
| 89 | +} |
| 90 | + |
| 91 | +.bz_time_tracking_table th { |
| 92 | + text-align: center; |
| 93 | +} |
| 94 | + |
| 95 | +.bz_time_tracking_table td { |
| 96 | + text-align: center; |
| 97 | +} |
| 98 | + |
| 99 | +.bz_time_tracking_table th, |
| 100 | +.bz_time_tracking_table td { |
| 101 | + padding: 4px; |
| 102 | +} |
| 103 | + |
| 104 | +.bz_time_tracking_table .bz_summarize_time { |
| 105 | + text-align: right; |
| 106 | +} |
| 107 | + |
| 108 | +#summary tr td { |
| 109 | + vertical-align:top; |
| 110 | +} |
| 111 | + |
| 112 | +#status { |
| 113 | + margin-bottom: 3ex; |
| 114 | +} |
| 115 | + |
| 116 | +.knob-buttons { |
| 117 | + float: right; |
| 118 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/video-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/video-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
1 | 119 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/search-fade.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/search-fade.png |
___________________________________________________________________ |
Added: svn:mime-type |
2 | 120 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/news-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/news-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
3 | 121 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/document-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/document-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
4 | 122 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/bugzilla-logo.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/bugzilla-logo.png |
___________________________________________________________________ |
Added: svn:mime-type |
5 | 123 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/mail-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/mail-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
6 | 124 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/preferences-base.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/preferences-base.png |
___________________________________________________________________ |
Added: svn:mime-type |
7 | 125 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/page-fade.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/page-fade.png |
___________________________________________________________________ |
Added: svn:mime-type |
8 | 126 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/bugzilla-badge.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/bugzilla-badge.png |
___________________________________________________________________ |
Added: svn:mime-type |
9 | 127 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/border.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/border.png |
___________________________________________________________________ |
Added: svn:mime-type |
10 | 128 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/watch-icons.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/watch-icons.png |
___________________________________________________________________ |
Added: svn:mime-type |
11 | 129 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/tab-current-fade.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/tab-current-fade.png |
___________________________________________________________________ |
Added: svn:mime-type |
12 | 130 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/preferences-break.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/preferences-break.png |
___________________________________________________________________ |
Added: svn:mime-type |
13 | 131 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/portal-break.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/portal-break.png |
___________________________________________________________________ |
Added: svn:mime-type |
14 | 132 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/audio-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/audio-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
15 | 133 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/watch-icon-loading.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/watch-icon-loading.gif |
___________________________________________________________________ |
Added: svn:mime-type |
16 | 134 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/tab-normal-fade.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/tab-normal-fade.png |
___________________________________________________________________ |
Added: svn:mime-type |
17 | 135 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/preferences-fade.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/preferences-fade.png |
___________________________________________________________________ |
Added: svn:mime-type |
18 | 136 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/external-link-rtl-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/external-link-rtl-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
19 | 137 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/external-link-ltr-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/external-link-ltr-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
20 | 138 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/block-base.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/block-base.png |
___________________________________________________________________ |
Added: svn:mime-type |
21 | 139 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/preferences-edge.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/preferences-edge.png |
___________________________________________________________________ |
Added: svn:mime-type |
22 | 140 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/user-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/user-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
23 | 141 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/search-ltr.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/search-ltr.png |
___________________________________________________________________ |
Added: svn:mime-type |
24 | 142 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/search-rtl.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/search-rtl.png |
___________________________________________________________________ |
Added: svn:mime-type |
25 | 143 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/file-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/file-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
26 | 144 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/edit-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/edit-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
27 | 145 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/bullet-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/bullet-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
28 | 146 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/lock-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/lock-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
29 | 147 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/magnify-clip.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/magnify-clip.png |
___________________________________________________________________ |
Added: svn:mime-type |
30 | 148 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/talk-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/talk-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
31 | 149 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/portal-break-rtl.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/portal-break-rtl.png |
___________________________________________________________________ |
Added: svn:mime-type |
32 | 150 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/portal-break-ltr.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/portal-break-ltr.png |
___________________________________________________________________ |
Added: svn:mime-type |
33 | 151 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/link-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/link-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
34 | 152 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/page-base.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/page-base.png |
___________________________________________________________________ |
Added: svn:mime-type |
35 | 153 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/arrow-down-icon.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/arrow-down-icon.png |
___________________________________________________________________ |
Added: svn:mime-type |
36 | 154 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/tab-break.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/images/tab-break.png |
___________________________________________________________________ |
Added: svn:mime-type |
37 | 155 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/bugzilla-ayb.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/bugzilla-ayb.png |
___________________________________________________________________ |
Added: svn:mime-type |
38 | 156 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/yui/calendar.css |
— | — | @@ -0,0 +1,7 @@ |
| 2 | +/* |
| 3 | +Copyright (c) 2008, Yahoo! Inc. All rights reserved. |
| 4 | +Code licensed under the BSD License: |
| 5 | +http://developer.yahoo.net/yui/license.txt |
| 6 | +version: 2.6.0 |
| 7 | +*/ |
| 8 | +.yui-calcontainer{position:relative;float:left;_overflow:hidden;}.yui-calcontainer iframe{position:absolute;border:none;margin:0;padding:0;z-index:0;width:100%;height:100%;left:0px;top:0px;}.yui-calcontainer iframe.fixedsize{width:50em;height:50em;top:-1px;left:-1px;}.yui-calcontainer.multi .groupcal{z-index:1;float:left;position:relative;}.yui-calcontainer .title{position:relative;z-index:1;}.yui-calcontainer .close-icon{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden;}.yui-calendar{position:relative;}.yui-calendar .calnavleft{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden;}.yui-calendar .calnavright{position:absolute;z-index:1;text-indent:-10000em;overflow:hidden;}.yui-calendar .calheader{position:relative;width:100%;text-align:center;}.yui-calcontainer .yui-cal-nav-mask{position:absolute;z-index:2;margin:0;padding:0;width:100%;height:100%;_width:0;_height:0;left:0;top:0;display:none;}.yui-calcontainer .yui-cal-nav{position:absolute;z-index:3;top:0;display:none;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{display:-moz-inline-box;display:inline-block;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{display:block;*display:inline-block;*overflow:visible;border:none;background-color:transparent;cursor:pointer;}.yui-calendar .calbody a:hover{background:inherit;}p#clear{clear:left;padding-top:10px;}.yui-skin-sam .yui-calcontainer{background-color:#f2f2f2;border:1px solid #808080;padding:10px;}.yui-skin-sam .yui-calcontainer.multi{padding:0 5px 0 5px;}.yui-skin-sam .yui-calcontainer.multi .groupcal{background-color:transparent;border:none;padding:10px 5px 10px 5px;margin:0;}.yui-skin-sam .yui-calcontainer .title{background:url(sprite.png) repeat-x 0 0;border-bottom:1px solid #cccccc;font:100% sans-serif;color:#000;font-weight:bold;height:auto;padding:.4em;margin:0 -10px 10px -10px;top:0;left:0;text-align:left;}.yui-skin-sam .yui-calcontainer.multi .title{margin:0 -5px 0 -5px;}.yui-skin-sam .yui-calcontainer.withtitle{padding-top:0;}.yui-skin-sam .yui-calcontainer .calclose{background:url(sprite.png) no-repeat 0 -300px;width:25px;height:15px;top:.4em;right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar{border-spacing:0;border-collapse:collapse;font:100% sans-serif;text-align:center;margin:0;}.yui-skin-sam .yui-calendar .calhead{background:transparent;border:none;vertical-align:middle;padding:0;}.yui-skin-sam .yui-calendar .calheader{background:transparent;font-weight:bold;padding:0 0 .6em 0;text-align:center;}.yui-skin-sam .yui-calendar .calheader img{border:none;}.yui-skin-sam .yui-calendar .calnavleft{background:url(sprite.png) no-repeat 0 -450px;width:25px;height:15px;top:0;bottom:0;left:-10px;margin-left:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calnavright{background:url(sprite.png) no-repeat 0 -500px;width:25px;height:15px;top:0;bottom:0;right:-10px;margin-right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calweekdayrow{height:2em;}.yui-skin-sam .yui-calendar .calweekdayrow th{padding:0;border:none;}.yui-skin-sam .yui-calendar .calweekdaycell{color:#000;font-weight:bold;text-align:center;width:2em;}.yui-skin-sam .yui-calendar .calfoot{background-color:#f2f2f2;}.yui-skin-sam .yui-calendar .calrowhead,.yui-skin-sam .yui-calendar .calrowfoot{color:#a6a6a6;font-size:85%;font-style:normal;font-weight:normal;border:none;}.yui-skin-sam .yui-calendar .calrowhead{text-align:right;padding:0 2px 0 0;}.yui-skin-sam .yui-calendar .calrowfoot{text-align:left;padding:0 0 0 2px;}.yui-skin-sam .yui-calendar td.calcell{border:1px solid #cccccc;background:#fff;padding:1px;height:1.6em;line-height:1.6em;text-align:center;white-space:nowrap;}.yui-skin-sam .yui-calendar td.calcell a{color:#0066cc;display:block;height:100%;text-decoration:none;}.yui-skin-sam .yui-calendar td.calcell.today{background-color:#000;}.yui-skin-sam .yui-calendar td.calcell.today a{background-color:#fff;}.yui-skin-sam .yui-calendar td.calcell.oom{background-color:#cccccc;color:#a6a6a6;cursor:default;}.yui-skin-sam .yui-calendar td.calcell.selected{background-color:#fff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.selected a{background-color:#b3d4ff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.calcellhover{background-color:#426fd9;color:#fff;cursor:pointer;}.yui-skin-sam .yui-calendar td.calcell.calcellhover a{background-color:#426fd9;color:#fff;}.yui-skin-sam .yui-calendar td.calcell.previous{color:#e0e0e0;}.yui-skin-sam .yui-calendar td.calcell.restricted{text-decoration:line-through;}.yui-skin-sam .yui-calendar td.calcell.highlight1{background-color:#ccff99;}.yui-skin-sam .yui-calendar td.calcell.highlight2{background-color:#99ccff;}.yui-skin-sam .yui-calendar td.calcell.highlight3{background-color:#ffcccc;}.yui-skin-sam .yui-calendar td.calcell.highlight4{background-color:#ccff99;}.yui-skin-sam .yui-calendar a.calnav{border:1px solid #f2f2f2;padding:0 4px;text-decoration:none;color:#000;zoom:1;}.yui-skin-sam .yui-calendar a.calnav:hover{background:url(sprite.png) repeat-x 0 0;border-color:#A0A0A0;cursor:pointer;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mask{background-color:#000;opacity:0.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-calcontainer .yui-cal-nav{font-family:arial,helvetica,clean,sans-serif;font-size:93%;border:1px solid #808080;left:50%;margin-left:-7em;width:14em;padding:0;top:2.5em;background-color:#f2f2f2;}.yui-skin-sam .yui-calcontainer.withtitle .yui-cal-nav{top:4.5em;}.yui-skin-sam .yui-calcontainer.multi .yui-cal-nav{width:16em;margin-left:-8em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y,.yui-skin-sam .yui-calcontainer .yui-cal-nav-m,.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{padding:5px 10px 5px 10px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{text-align:center;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-e{margin-top:5px;padding:5px;background-color:#EDF5FF;border-top:1px solid black;display:none;}.yui-skin-sam .yui-calcontainer .yui-cal-nav label{display:block;font-weight:bold;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mc{width:100%;_width:auto;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y input.yui-invalid{background-color:#FFEE69;border:1px solid #000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-yc{width:4em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{border:1px solid #808080;background:url(sprite.png) repeat-x 0 0;background-color:#ccc;margin:auto .15em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{padding:0 8px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default{border:1px solid #304369;background-color:#426fd9;background:url(sprite.png) repeat-x 0 -1400px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default button{color:#fff;} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/yui/sprite.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/yui/sprite.png |
___________________________________________________________________ |
Added: svn:mime-type |
1 | 9 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/params.css |
— | — | @@ -0,0 +1,61 @@ |
| 2 | +#menu { |
| 3 | + width: 10em; |
| 4 | + margin-top: 1em; |
| 5 | + margin-right: 0.5em; |
| 6 | + border: solid thin; |
| 7 | + border-spacing: 0px; |
| 8 | + border-collapse: collapse; |
| 9 | + text-align: center; |
| 10 | + color: black; |
| 11 | + background-color: #edf2f2; |
| 12 | + font-weight: normal; |
| 13 | +} |
| 14 | + |
| 15 | +#menu a:link, #menu a:visited { |
| 16 | + color: #039; |
| 17 | + background-color: transparent; |
| 18 | +} |
| 19 | + |
| 20 | +#menu a:hover, #menu a:active { |
| 21 | + color: red; |
| 22 | + background-color: transparent; |
| 23 | +} |
| 24 | + |
| 25 | +#menu td { |
| 26 | + border: solid thin; |
| 27 | + padding: 0.2em 0.5em; |
| 28 | +} |
| 29 | + |
| 30 | +table td { |
| 31 | + vertical-align: top; |
| 32 | +} |
| 33 | + |
| 34 | +td.selected_section { |
| 35 | + color: #090; |
| 36 | + background-color: white; |
| 37 | +} |
| 38 | + |
| 39 | +td.index { |
| 40 | + color: black; |
| 41 | + background-color: #edf; |
| 42 | +} |
| 43 | + |
| 44 | +dt { |
| 45 | + font-weight: bold; |
| 46 | +} |
| 47 | + |
| 48 | +dd { |
| 49 | + margin-bottom: 1.5em; |
| 50 | +} |
| 51 | + |
| 52 | +.sortlist_separator { |
| 53 | + font-weight: bold; |
| 54 | + font-size: 80%; |
| 55 | + background-color: #dddddd; |
| 56 | +} |
| 57 | + |
| 58 | +.contribute { |
| 59 | + border: 1px dotted black; |
| 60 | + padding: .5em; |
| 61 | + font-size: small; |
| 62 | +} |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/dependency-tree/tree-open.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/dependency-tree/tree-open.png |
___________________________________________________________________ |
Added: svn:mime-type |
1 | 63 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/dependency-tree/tree.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/dependency-tree/tree.png |
___________________________________________________________________ |
Added: svn:mime-type |
2 | 64 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/dependency-tree/tree-closed.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/dependency-tree/tree-closed.png |
___________________________________________________________________ |
Added: svn:mime-type |
3 | 65 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/dependency-tree/bug-item.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/tools/bugzilla/bugzilla-3.6.2/skins/custom/dependency-tree/bug-item.png |
___________________________________________________________________ |
Added: svn:mime-type |
4 | 66 | + application/octet-stream |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/Bugzilla/Template.pm |
— | — | @@ -0,0 +1,977 @@ |
| 2 | +# -*- Mode: perl; indent-tabs-mode: nil -*- |
| 3 | +# |
| 4 | +# The contents of this file are subject to the Mozilla Public |
| 5 | +# License Version 1.1 (the "License"); you may not use this file |
| 6 | +# except in compliance with the License. You may obtain a copy of |
| 7 | +# the License at http://www.mozilla.org/MPL/ |
| 8 | +# |
| 9 | +# Software distributed under the License is distributed on an "AS |
| 10 | +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 | +# implied. See the License for the specific language governing |
| 12 | +# rights and limitations under the License. |
| 13 | +# |
| 14 | +# The Original Code is the Bugzilla Bug Tracking System. |
| 15 | +# |
| 16 | +# The Initial Developer of the Original Code is Netscape Communications |
| 17 | +# Corporation. Portions created by Netscape are |
| 18 | +# Copyright (C) 1998 Netscape Communications Corporation. All |
| 19 | +# Rights Reserved. |
| 20 | +# |
| 21 | +# Contributor(s): Terry Weissman <terry@mozilla.org> |
| 22 | +# Dan Mosedale <dmose@mozilla.org> |
| 23 | +# Jacob Steenhagen <jake@bugzilla.org> |
| 24 | +# Bradley Baetz <bbaetz@student.usyd.edu.au> |
| 25 | +# Christopher Aillon <christopher@aillon.com> |
| 26 | +# Tobias Burnus <burnus@net-b.de> |
| 27 | +# Myk Melez <myk@mozilla.org> |
| 28 | +# Max Kanat-Alexander <mkanat@bugzilla.org> |
| 29 | +# Frédéric Buclin <LpSolit@gmail.com> |
| 30 | +# Greg Hendricks <ghendricks@novell.com> |
| 31 | +# David D. Kilzer <ddkilzer@kilzer.net> |
| 32 | + |
| 33 | + |
| 34 | +package Bugzilla::Template; |
| 35 | + |
| 36 | +use strict; |
| 37 | + |
| 38 | +use Bugzilla::Bug; |
| 39 | +use Bugzilla::Constants; |
| 40 | +use Bugzilla::Hook; |
| 41 | +use Bugzilla::Install::Requirements; |
| 42 | +use Bugzilla::Install::Util qw(install_string template_include_path |
| 43 | + include_languages); |
| 44 | +use Bugzilla::Keyword; |
| 45 | +use Bugzilla::Util; |
| 46 | +use Bugzilla::User; |
| 47 | +use Bugzilla::Error; |
| 48 | +use Bugzilla::Status; |
| 49 | +use Bugzilla::Token; |
| 50 | + |
| 51 | +use Cwd qw(abs_path); |
| 52 | +use MIME::Base64; |
| 53 | +use Date::Format (); |
| 54 | +use File::Basename qw(basename dirname); |
| 55 | +use File::Find; |
| 56 | +use File::Path qw(rmtree mkpath); |
| 57 | +use File::Spec; |
| 58 | +use IO::Dir; |
| 59 | +use Scalar::Util qw(blessed); |
| 60 | + |
| 61 | +use base qw(Template); |
| 62 | + |
| 63 | +# Convert the constants in the Bugzilla::Constants module into a hash we can |
| 64 | +# pass to the template object for reflection into its "constants" namespace |
| 65 | +# (which is like its "variables" namespace, but for constants). To do so, we |
| 66 | +# traverse the arrays of exported and exportable symbols and ignoring the rest |
| 67 | +# (which, if Constants.pm exports only constants, as it should, will be nothing else). |
| 68 | +sub _load_constants { |
| 69 | + my %constants; |
| 70 | + foreach my $constant (@Bugzilla::Constants::EXPORT, |
| 71 | + @Bugzilla::Constants::EXPORT_OK) |
| 72 | + { |
| 73 | + if (ref Bugzilla::Constants->$constant) { |
| 74 | + $constants{$constant} = Bugzilla::Constants->$constant; |
| 75 | + } |
| 76 | + else { |
| 77 | + my @list = (Bugzilla::Constants->$constant); |
| 78 | + $constants{$constant} = (scalar(@list) == 1) ? $list[0] : \@list; |
| 79 | + } |
| 80 | + } |
| 81 | + return \%constants; |
| 82 | +} |
| 83 | + |
| 84 | +# Returns the path to the templates based on the Accept-Language |
| 85 | +# settings of the user and of the available languages |
| 86 | +# If no Accept-Language is present it uses the defined default |
| 87 | +# Templates may also be found in the extensions/ tree |
| 88 | +sub getTemplateIncludePath { |
| 89 | + my $cache = Bugzilla->request_cache; |
| 90 | + my $lang = $cache->{'language'} || ''; |
| 91 | + $cache->{"template_include_path_$lang"} ||= template_include_path({ |
| 92 | + use_languages => Bugzilla->languages, |
| 93 | + only_language => $lang }); |
| 94 | + return $cache->{"template_include_path_$lang"}; |
| 95 | +} |
| 96 | + |
| 97 | +sub get_format { |
| 98 | + my $self = shift; |
| 99 | + my ($template, $format, $ctype) = @_; |
| 100 | + |
| 101 | + $ctype ||= 'html'; |
| 102 | + $format ||= ''; |
| 103 | + |
| 104 | + # Security - allow letters and a hyphen only |
| 105 | + $ctype =~ s/[^a-zA-Z\-]//g; |
| 106 | + $format =~ s/[^a-zA-Z\-]//g; |
| 107 | + trick_taint($ctype); |
| 108 | + trick_taint($format); |
| 109 | + |
| 110 | + $template .= ($format ? "-$format" : ""); |
| 111 | + $template .= ".$ctype.tmpl"; |
| 112 | + |
| 113 | + # Now check that the template actually exists. We only want to check |
| 114 | + # if the template exists; any other errors (eg parse errors) will |
| 115 | + # end up being detected later. |
| 116 | + eval { |
| 117 | + $self->context->template($template); |
| 118 | + }; |
| 119 | + # This parsing may seem fragile, but it's OK: |
| 120 | + # http://lists.template-toolkit.org/pipermail/templates/2003-March/004370.html |
| 121 | + # Even if it is wrong, any sort of error is going to cause a failure |
| 122 | + # eventually, so the only issue would be an incorrect error message |
| 123 | + if ($@ && $@->info =~ /: not found$/) { |
| 124 | + ThrowUserError('format_not_found', {'format' => $format, |
| 125 | + 'ctype' => $ctype}); |
| 126 | + } |
| 127 | + |
| 128 | + # Else, just return the info |
| 129 | + return |
| 130 | + { |
| 131 | + 'template' => $template, |
| 132 | + 'extension' => $ctype, |
| 133 | + 'ctype' => Bugzilla::Constants::contenttypes->{$ctype} |
| 134 | + }; |
| 135 | +} |
| 136 | + |
| 137 | +# This routine quoteUrls contains inspirations from the HTML::FromText CPAN |
| 138 | +# module by Gareth Rees <garethr@cre.canon.co.uk>. It has been heavily hacked, |
| 139 | +# all that is really recognizable from the original is bits of the regular |
| 140 | +# expressions. |
| 141 | +# This has been rewritten to be faster, mainly by substituting 'as we go'. |
| 142 | +# If you want to modify this routine, read the comments carefully |
| 143 | + |
| 144 | +sub quoteUrls { |
| 145 | + my ($text, $bug, $comment) = (@_); |
| 146 | + return $text unless $text; |
| 147 | + |
| 148 | + # We use /g for speed, but uris can have other things inside them |
| 149 | + # (http://foo/bug#3 for example). Filtering that out filters valid |
| 150 | + # bug refs out, so we have to do replacements. |
| 151 | + # mailto can't contain space or #, so we don't have to bother for that |
| 152 | + # Do this by escaping \0 to \1\0, and replacing matches with \0\0$count\0\0 |
| 153 | + # \0 is used because it's unlikely to occur in the text, so the cost of |
| 154 | + # doing this should be very small |
| 155 | + |
| 156 | + # escape the 2nd escape char we're using |
| 157 | + my $chr1 = chr(1); |
| 158 | + $text =~ s/\0/$chr1\0/g; |
| 159 | + |
| 160 | + # However, note that adding the title (for buglinks) can affect things |
| 161 | + # In particular, attachment matches go before bug titles, so that titles |
| 162 | + # with 'attachment 1' don't double match. |
| 163 | + # Dupe checks go afterwards, because that uses ^ and \Z, which won't occur |
| 164 | + # if it was substituted as a bug title (since that always involve leading |
| 165 | + # and trailing text) |
| 166 | + |
| 167 | + # Because of entities, it's easier (and quicker) to do this before escaping |
| 168 | + |
| 169 | + my @things; |
| 170 | + my $count = 0; |
| 171 | + my $tmp; |
| 172 | + |
| 173 | + my @hook_regexes; |
| 174 | + Bugzilla::Hook::process('bug_format_comment', |
| 175 | + { text => \$text, bug => $bug, regexes => \@hook_regexes, |
| 176 | + comment => $comment }); |
| 177 | + |
| 178 | + foreach my $re (@hook_regexes) { |
| 179 | + my ($match, $replace) = @$re{qw(match replace)}; |
| 180 | + if (ref($replace) eq 'CODE') { |
| 181 | + $text =~ s/$match/($things[$count++] = $replace->({matches => [ |
| 182 | + $1, $2, $3, $4, |
| 183 | + $5, $6, $7, $8, |
| 184 | + $9, $10]})) |
| 185 | + && ("\0\0" . ($count-1) . "\0\0")/egx; |
| 186 | + } |
| 187 | + else { |
| 188 | + $text =~ s/$match/($things[$count++] = $replace) |
| 189 | + && ("\0\0" . ($count-1) . "\0\0")/egx; |
| 190 | + } |
| 191 | + } |
| 192 | + |
| 193 | + # Provide tooltips for full bug links (Bug 74355) |
| 194 | + my $urlbase_re = '(' . join('|', |
| 195 | + map { qr/$_/ } grep($_, Bugzilla->params->{'urlbase'}, |
| 196 | + Bugzilla->params->{'sslbase'})) . ')'; |
| 197 | + $text =~ s~\b(${urlbase_re}\Qshow_bug.cgi?id=\E([0-9]+)(\#c([0-9]+))?)\b |
| 198 | + ~($things[$count++] = get_bug_link($3, $1, { comment_num => $5 })) && |
| 199 | + ("\0\0" . ($count-1) . "\0\0") |
| 200 | + ~egox; |
| 201 | + |
| 202 | + # ####### Working on changing this to a template hook --pdhanda |
| 203 | + # **** Dirty hack! --brion |
| 204 | + $text =~ s~\[\[([a-zA-Z0-9_ ,./'()!#%:\x80-\xff-]+)\]\] |
| 205 | + ~($tmp = html_quote($1)) && |
| 206 | + ($things[$count++] = "<a href=\"http://en.wikipedia.org/wiki/$tmp\">[[$tmp]]</a>") && |
| 207 | + ("\0\0" . ($count-1) . "\0\0") |
| 208 | + ~egox; |
| 209 | + # **** end dirty hack |
| 210 | + # **** More dirty hacks! --brion |
| 211 | + $text =~ s~\br(\d+)\b |
| 212 | + ~($things[$count++] = "<a href=\"http://www.mediawiki.org" . |
| 213 | + "/wiki/Special:Code/MediaWiki/$1\" " . |
| 214 | + "title=\"revision $1 in SVN\">r$1</a>") && |
| 215 | + ("\0\0" . ($count-1) . "\0\0") |
| 216 | + ~egox; |
| 217 | + # **** end dirty hack |
| 218 | + |
| 219 | + # non-mailto protocols |
| 220 | + my $safe_protocols = join('|', SAFE_PROTOCOLS); |
| 221 | + my $protocol_re = qr/($safe_protocols)/i; |
| 222 | + |
| 223 | + $text =~ s~\b(${protocol_re}: # The protocol: |
| 224 | + [^\s<>\"]+ # Any non-whitespace |
| 225 | + [\w\/]) # so that we end in \w or / |
| 226 | + ~($tmp = html_quote($1)) && |
| 227 | + ($things[$count++] = "<a href=\"$tmp\">$tmp</a>") && |
| 228 | + ("\0\0" . ($count-1) . "\0\0") |
| 229 | + ~egox; |
| 230 | + |
| 231 | + # We have to quote now, otherwise the html itself is escaped |
| 232 | + # THIS MEANS THAT A LITERAL ", <, >, ' MUST BE ESCAPED FOR A MATCH |
| 233 | + |
| 234 | + $text = html_quote($text); |
| 235 | + |
| 236 | + # Color quoted text |
| 237 | + $text =~ s~^(>.+)$~<span class="quote">$1</span >~mg; |
| 238 | + $text =~ s~</span >\n<span class="quote">~\n~g; |
| 239 | + |
| 240 | + # mailto: |
| 241 | + # Use |<nothing> so that $1 is defined regardless |
| 242 | + $text =~ s~\b(mailto:|)?([\w\.\-\+\=]+\@[\w\-]+(?:\.[\w\-]+)+)\b |
| 243 | + ~<a href=\"mailto:$2\">$1$2</a>~igx; |
| 244 | + |
| 245 | + # attachment links |
| 246 | + $text =~ s~\b(attachment\s*\#?\s*(\d+)) |
| 247 | + ~($things[$count++] = get_attachment_link($2, $1)) && |
| 248 | + ("\0\0" . ($count-1) . "\0\0") |
| 249 | + ~egmxi; |
| 250 | + |
| 251 | + # Current bug ID this comment belongs to |
| 252 | + my $current_bugurl = $bug ? ("show_bug.cgi?id=" . $bug->id) : ""; |
| 253 | + |
| 254 | + # This handles bug a, comment b type stuff. Because we're using /g |
| 255 | + # we have to do this in one pattern, and so this is semi-messy. |
| 256 | + # Also, we can't use $bug_re?$comment_re? because that will match the |
| 257 | + # empty string |
| 258 | + my $bug_word = template_var('terms')->{bug}; |
| 259 | + my $bug_re = qr/\Q$bug_word\E\s*\#?\s*(\d+)/i; |
| 260 | + my $comment_re = qr/comment\s*\#?\s*(\d+)/i; |
| 261 | + $text =~ s~\b($bug_re(?:\s*,?\s*$comment_re)?|$comment_re) |
| 262 | + ~ # We have several choices. $1 here is the link, and $2-4 are set |
| 263 | + # depending on which part matched |
| 264 | + (defined($2) ? get_bug_link($2, $1, { comment_num => $3 }) : |
| 265 | + "<a href=\"$current_bugurl#c$4\">$1</a>") |
| 266 | + ~egox; |
| 267 | + |
| 268 | + # Old duplicate markers. These don't use $bug_word because they are old |
| 269 | + # and were never customizable. |
| 270 | + $text =~ s~(?<=^\*\*\*\ This\ bug\ has\ been\ marked\ as\ a\ duplicate\ of\ ) |
| 271 | + (\d+) |
| 272 | + (?=\ \*\*\*\Z) |
| 273 | + ~get_bug_link($1, $1) |
| 274 | + ~egmx; |
| 275 | + |
| 276 | + # Now remove the encoding hacks |
| 277 | + $text =~ s/\0\0(\d+)\0\0/$things[$1]/eg; |
| 278 | + $text =~ s/$chr1\0/\0/g; |
| 279 | + |
| 280 | + return $text; |
| 281 | +} |
| 282 | + |
| 283 | +# Creates a link to an attachment, including its title. |
| 284 | +sub get_attachment_link { |
| 285 | + my ($attachid, $link_text) = @_; |
| 286 | + my $dbh = Bugzilla->dbh; |
| 287 | + |
| 288 | + my $attachment = new Bugzilla::Attachment($attachid); |
| 289 | + |
| 290 | + if ($attachment) { |
| 291 | + my $title = ""; |
| 292 | + my $className = ""; |
| 293 | + if (Bugzilla->user->can_see_bug($attachment->bug_id)) { |
| 294 | + $title = $attachment->description; |
| 295 | + } |
| 296 | + if ($attachment->isobsolete) { |
| 297 | + $className = "bz_obsolete"; |
| 298 | + } |
| 299 | + # Prevent code injection in the title. |
| 300 | + $title = html_quote(clean_text($title)); |
| 301 | + |
| 302 | + $link_text =~ s/ \[details\]$//; |
| 303 | + my $linkval = "attachment.cgi?id=$attachid"; |
| 304 | + |
| 305 | + # If the attachment is a patch, try to link to the diff rather |
| 306 | + # than the text, by default. |
| 307 | + my $patchlink = ""; |
| 308 | + if ($attachment->ispatch and Bugzilla->feature('patch_viewer')) { |
| 309 | + $patchlink = '&action=diff'; |
| 310 | + } |
| 311 | + |
| 312 | + # Whitespace matters here because these links are in <pre> tags. |
| 313 | + return qq|<span class="$className">| |
| 314 | + . qq|<a href="${linkval}${patchlink}" name="attach_${attachid}" title="$title">$link_text</a>| |
| 315 | + . qq| <a href="${linkval}&action=edit" title="$title">[details]</a>| |
| 316 | + . qq|</span>|; |
| 317 | + } |
| 318 | + else { |
| 319 | + return qq{$link_text}; |
| 320 | + } |
| 321 | +} |
| 322 | + |
| 323 | +# Creates a link to a bug, including its title. |
| 324 | +# It takes either two or three parameters: |
| 325 | +# - The bug number |
| 326 | +# - The link text, to place between the <a>..</a> |
| 327 | +# - An optional comment number, for linking to a particular |
| 328 | +# comment in the bug |
| 329 | + |
| 330 | +sub get_bug_link { |
| 331 | + my ($bug, $link_text, $options) = @_; |
| 332 | + my $dbh = Bugzilla->dbh; |
| 333 | + |
| 334 | + if (!$bug) { |
| 335 | + return html_quote('<missing bug number>'); |
| 336 | + } |
| 337 | + |
| 338 | + $bug = blessed($bug) ? $bug : new Bugzilla::Bug($bug); |
| 339 | + return $link_text if $bug->{error}; |
| 340 | + |
| 341 | + # Initialize these variables to be "" so that we don't get warnings |
| 342 | + # if we don't change them below (which is highly likely). |
| 343 | + my ($pre, $title, $post) = ("", "", ""); |
| 344 | + |
| 345 | + $title = get_text('get_status', { status => $bug->bug_status }); |
| 346 | + if ($bug->bug_status eq 'UNCONFIRMED') { |
| 347 | + $pre = "<i>"; |
| 348 | + $post = "</i>"; |
| 349 | + } |
| 350 | + if ($bug->resolution) { |
| 351 | + $pre .= '<span class="bz_closed">'; |
| 352 | + $title .= ' ' . get_text('get_resolution', |
| 353 | + { resolution => $bug->resolution }); |
| 354 | + $post .= '</span>'; |
| 355 | + } |
| 356 | + if (Bugzilla->user->can_see_bug($bug)) { |
| 357 | + $title .= " - " . $bug->short_desc; |
| 358 | + if ($options->{use_alias} && $link_text =~ /^\d+$/ && $bug->alias) { |
| 359 | + $link_text = $bug->alias; |
| 360 | + } |
| 361 | + } |
| 362 | + # Prevent code injection in the title. |
| 363 | + $title = html_quote(clean_text($title)); |
| 364 | + |
| 365 | + my $linkval = "show_bug.cgi?id=" . $bug->id; |
| 366 | + if (defined $options->{comment_num}) { |
| 367 | + $linkval .= "#c" . $options->{comment_num}; |
| 368 | + } |
| 369 | + return qq{$pre<a href="$linkval" title="$title">$link_text</a>$post}; |
| 370 | +} |
| 371 | + |
| 372 | +############################################################################### |
| 373 | +# Templatization Code |
| 374 | + |
| 375 | +# The Template Toolkit throws an error if a loop iterates >1000 times. |
| 376 | +# We want to raise that limit. |
| 377 | +# NOTE: If you change this number, you MUST RE-RUN checksetup.pl!!! |
| 378 | +# If you do not re-run checksetup.pl, the change you make will not apply |
| 379 | +$Template::Directive::WHILE_MAX = 1000000; |
| 380 | + |
| 381 | +# Use the Toolkit Template's Stash module to add utility pseudo-methods |
| 382 | +# to template variables. |
| 383 | +use Template::Stash; |
| 384 | + |
| 385 | +# Allow keys to start with an underscore or a dot. |
| 386 | +$Template::Stash::PRIVATE = undef; |
| 387 | + |
| 388 | +# Add "contains***" methods to list variables that search for one or more |
| 389 | +# items in a list and return boolean values representing whether or not |
| 390 | +# one/all/any item(s) were found. |
| 391 | +$Template::Stash::LIST_OPS->{ contains } = |
| 392 | + sub { |
| 393 | + my ($list, $item) = @_; |
| 394 | + return grep($_ eq $item, @$list); |
| 395 | + }; |
| 396 | + |
| 397 | +$Template::Stash::LIST_OPS->{ containsany } = |
| 398 | + sub { |
| 399 | + my ($list, $items) = @_; |
| 400 | + foreach my $item (@$items) { |
| 401 | + return 1 if grep($_ eq $item, @$list); |
| 402 | + } |
| 403 | + return 0; |
| 404 | + }; |
| 405 | + |
| 406 | +# Clone the array reference to leave the original one unaltered. |
| 407 | +$Template::Stash::LIST_OPS->{ clone } = |
| 408 | + sub { |
| 409 | + my $list = shift; |
| 410 | + return [@$list]; |
| 411 | + }; |
| 412 | + |
| 413 | +# Allow us to still get the scalar if we use the list operation ".0" on it, |
| 414 | +# as we often do for defaults in query.cgi and other places. |
| 415 | +$Template::Stash::SCALAR_OPS->{ 0 } = |
| 416 | + sub { |
| 417 | + return $_[0]; |
| 418 | + }; |
| 419 | + |
| 420 | +# Add a "substr" method to the Template Toolkit's "scalar" object |
| 421 | +# that returns a substring of a string. |
| 422 | +$Template::Stash::SCALAR_OPS->{ substr } = |
| 423 | + sub { |
| 424 | + my ($scalar, $offset, $length) = @_; |
| 425 | + return substr($scalar, $offset, $length); |
| 426 | + }; |
| 427 | + |
| 428 | +# Add a "truncate" method to the Template Toolkit's "scalar" object |
| 429 | +# that truncates a string to a certain length. |
| 430 | +$Template::Stash::SCALAR_OPS->{ truncate } = |
| 431 | + sub { |
| 432 | + my ($string, $length, $ellipsis) = @_; |
| 433 | + $ellipsis ||= ""; |
| 434 | + |
| 435 | + return $string if !$length || length($string) <= $length; |
| 436 | + |
| 437 | + my $strlen = $length - length($ellipsis); |
| 438 | + my $newstr = substr($string, 0, $strlen) . $ellipsis; |
| 439 | + return $newstr; |
| 440 | + }; |
| 441 | + |
| 442 | +# Create the template object that processes templates and specify |
| 443 | +# configuration parameters that apply to all templates. |
| 444 | + |
| 445 | +############################################################################### |
| 446 | + |
| 447 | +# Construct the Template object |
| 448 | + |
| 449 | +# Note that all of the failure cases here can't use templateable errors, |
| 450 | +# since we won't have a template to use... |
| 451 | + |
| 452 | +sub create { |
| 453 | + my $class = shift; |
| 454 | + my %opts = @_; |
| 455 | + |
| 456 | + # IMPORTANT - If you make any FILTER changes here, make sure to |
| 457 | + # make them in t/004.template.t also, if required. |
| 458 | + |
| 459 | + my $config = { |
| 460 | + # Colon-separated list of directories containing templates. |
| 461 | + INCLUDE_PATH => $opts{'include_path'} || getTemplateIncludePath(), |
| 462 | + |
| 463 | + # Remove white-space before template directives (PRE_CHOMP) and at the |
| 464 | + # beginning and end of templates and template blocks (TRIM) for better |
| 465 | + # looking, more compact content. Use the plus sign at the beginning |
| 466 | + # of directives to maintain white space (i.e. [%+ DIRECTIVE %]). |
| 467 | + PRE_CHOMP => 1, |
| 468 | + TRIM => 1, |
| 469 | + |
| 470 | + # Bugzilla::Template::Plugin::Hook uses the absolute (in mod_perl) |
| 471 | + # or relative (in mod_cgi) paths of hook files to explicitly compile |
| 472 | + # a specific file. Also, these paths may be absolute at any time |
| 473 | + # if a packager has modified bz_locations() to contain absolute |
| 474 | + # paths. |
| 475 | + ABSOLUTE => 1, |
| 476 | + RELATIVE => $ENV{MOD_PERL} ? 0 : 1, |
| 477 | + |
| 478 | + COMPILE_DIR => bz_locations()->{'datadir'} . "/template", |
| 479 | + |
| 480 | + # Initialize templates (f.e. by loading plugins like Hook). |
| 481 | + PRE_PROCESS => ["global/initialize.none.tmpl"], |
| 482 | + |
| 483 | + ENCODING => Bugzilla->params->{'utf8'} ? 'UTF-8' : undef, |
| 484 | + |
| 485 | + # Functions for processing text within templates in various ways. |
| 486 | + # IMPORTANT! When adding a filter here that does not override a |
| 487 | + # built-in filter, please also add a stub filter to t/004template.t. |
| 488 | + FILTERS => { |
| 489 | + |
| 490 | + # Render text in required style. |
| 491 | + |
| 492 | + inactive => [ |
| 493 | + sub { |
| 494 | + my($context, $isinactive) = @_; |
| 495 | + return sub { |
| 496 | + return $isinactive ? '<span class="bz_inactive">'.$_[0].'</span>' : $_[0]; |
| 497 | + } |
| 498 | + }, 1 |
| 499 | + ], |
| 500 | + |
| 501 | + closed => [ |
| 502 | + sub { |
| 503 | + my($context, $isclosed) = @_; |
| 504 | + return sub { |
| 505 | + return $isclosed ? '<span class="bz_closed">'.$_[0].'</span>' : $_[0]; |
| 506 | + } |
| 507 | + }, 1 |
| 508 | + ], |
| 509 | + |
| 510 | + obsolete => [ |
| 511 | + sub { |
| 512 | + my($context, $isobsolete) = @_; |
| 513 | + return sub { |
| 514 | + return $isobsolete ? '<span class="bz_obsolete">'.$_[0].'</span>' : $_[0]; |
| 515 | + } |
| 516 | + }, 1 |
| 517 | + ], |
| 518 | + |
| 519 | + # Returns the text with backslashes, single/double quotes, |
| 520 | + # and newlines/carriage returns escaped for use in JS strings. |
| 521 | + js => sub { |
| 522 | + my ($var) = @_; |
| 523 | + $var =~ s/([\\\'\"\/])/\\$1/g; |
| 524 | + $var =~ s/\n/\\n/g; |
| 525 | + $var =~ s/\r/\\r/g; |
| 526 | + $var =~ s/\@/\\x40/g; # anti-spam for email addresses |
| 527 | + $var =~ s/</\\x3c/g; |
| 528 | + return $var; |
| 529 | + }, |
| 530 | + |
| 531 | + # Converts data to base64 |
| 532 | + base64 => sub { |
| 533 | + my ($data) = @_; |
| 534 | + return encode_base64($data); |
| 535 | + }, |
| 536 | + |
| 537 | + # HTML collapses newlines in element attributes to a single space, |
| 538 | + # so form elements which may have whitespace (ie comments) need |
| 539 | + # to be encoded using 
 |
| 540 | + # See bugs 4928, 22983 and 32000 for more details |
| 541 | + html_linebreak => sub { |
| 542 | + my ($var) = @_; |
| 543 | + $var =~ s/\r\n/\
/g; |
| 544 | + $var =~ s/\n\r/\
/g; |
| 545 | + $var =~ s/\r/\
/g; |
| 546 | + $var =~ s/\n/\
/g; |
| 547 | + return $var; |
| 548 | + }, |
| 549 | + |
| 550 | + # Prevents line break on hyphens and whitespaces. |
| 551 | + no_break => sub { |
| 552 | + my ($var) = @_; |
| 553 | + $var =~ s/ /\ /g; |
| 554 | + $var =~ s/-/\‑/g; |
| 555 | + return $var; |
| 556 | + }, |
| 557 | + |
| 558 | + xml => \&Bugzilla::Util::xml_quote , |
| 559 | + |
| 560 | + # This filter escapes characters in a variable or value string for |
| 561 | + # use in a query string. It escapes all characters NOT in the |
| 562 | + # regex set: [a-zA-Z0-9_\-.]. The 'uri' filter should be used for |
| 563 | + # a full URL that may have characters that need encoding. |
| 564 | + url_quote => \&Bugzilla::Util::url_quote , |
| 565 | + |
| 566 | + # This filter is similar to url_quote but used a \ instead of a % |
| 567 | + # as prefix. In addition it replaces a ' ' by a '_'. |
| 568 | + css_class_quote => \&Bugzilla::Util::css_class_quote , |
| 569 | + |
| 570 | + quoteUrls => [ sub { |
| 571 | + my ($context, $bug, $comment) = @_; |
| 572 | + return sub { |
| 573 | + my $text = shift; |
| 574 | + return quoteUrls($text, $bug, $comment); |
| 575 | + }; |
| 576 | + }, |
| 577 | + 1 |
| 578 | + ], |
| 579 | + |
| 580 | + bug_link => [ sub { |
| 581 | + my ($context, $bug, $options) = @_; |
| 582 | + return sub { |
| 583 | + my $text = shift; |
| 584 | + return get_bug_link($bug, $text, $options); |
| 585 | + }; |
| 586 | + }, |
| 587 | + 1 |
| 588 | + ], |
| 589 | + |
| 590 | + bug_list_link => sub |
| 591 | + { |
| 592 | + my $buglist = shift; |
| 593 | + return join(", ", map(get_bug_link($_, $_), split(/ *, */, $buglist))); |
| 594 | + }, |
| 595 | + |
| 596 | + # In CSV, quotes are doubled, and any value containing a quote or a |
| 597 | + # comma is enclosed in quotes. |
| 598 | + csv => sub |
| 599 | + { |
| 600 | + my ($var) = @_; |
| 601 | + $var =~ s/\"/\"\"/g; |
| 602 | + if ($var !~ /^-?(\d+\.)?\d*$/) { |
| 603 | + $var = "\"$var\""; |
| 604 | + } |
| 605 | + return $var; |
| 606 | + } , |
| 607 | + |
| 608 | + # Format a filesize in bytes to a human readable value |
| 609 | + unitconvert => sub |
| 610 | + { |
| 611 | + my ($data) = @_; |
| 612 | + my $retval = ""; |
| 613 | + my %units = ( |
| 614 | + 'KB' => 1024, |
| 615 | + 'MB' => 1024 * 1024, |
| 616 | + 'GB' => 1024 * 1024 * 1024, |
| 617 | + ); |
| 618 | + |
| 619 | + if ($data < 1024) { |
| 620 | + return "$data bytes"; |
| 621 | + } |
| 622 | + else { |
| 623 | + my $u; |
| 624 | + foreach $u ('GB', 'MB', 'KB') { |
| 625 | + if ($data >= $units{$u}) { |
| 626 | + return sprintf("%.2f %s", $data/$units{$u}, $u); |
| 627 | + } |
| 628 | + } |
| 629 | + } |
| 630 | + }, |
| 631 | + |
| 632 | + # Format a time for display (more info in Bugzilla::Util) |
| 633 | + time => [ sub { |
| 634 | + my ($context, $format, $timezone) = @_; |
| 635 | + return sub { |
| 636 | + my $time = shift; |
| 637 | + return format_time($time, $format, $timezone); |
| 638 | + }; |
| 639 | + }, |
| 640 | + 1 |
| 641 | + ], |
| 642 | + |
| 643 | + html => \&Bugzilla::Util::html_quote, |
| 644 | + |
| 645 | + html_light => \&Bugzilla::Util::html_light_quote, |
| 646 | + |
| 647 | + email => \&Bugzilla::Util::email_filter, |
| 648 | + |
| 649 | + # iCalendar contentline filter |
| 650 | + ics => [ sub { |
| 651 | + my ($context, @args) = @_; |
| 652 | + return sub { |
| 653 | + my ($var) = shift; |
| 654 | + my ($par) = shift @args; |
| 655 | + my ($output) = ""; |
| 656 | + |
| 657 | + $var =~ s/[\r\n]/ /g; |
| 658 | + $var =~ s/([;\\\",])/\\$1/g; |
| 659 | + |
| 660 | + if ($par) { |
| 661 | + $output = sprintf("%s:%s", $par, $var); |
| 662 | + } else { |
| 663 | + $output = $var; |
| 664 | + } |
| 665 | + |
| 666 | + $output =~ s/(.{75,75})/$1\n /g; |
| 667 | + |
| 668 | + return $output; |
| 669 | + }; |
| 670 | + }, |
| 671 | + 1 |
| 672 | + ], |
| 673 | + |
| 674 | + # Note that using this filter is even more dangerous than |
| 675 | + # using "none," and you should only use it when you're SURE |
| 676 | + # the output won't be displayed directly to a web browser. |
| 677 | + txt => sub { |
| 678 | + my ($var) = @_; |
| 679 | + # Trivial HTML tag remover |
| 680 | + $var =~ s/<[^>]*>//g; |
| 681 | + # And this basically reverses the html filter. |
| 682 | + $var =~ s/\@/@/g; |
| 683 | + $var =~ s/\</</g; |
| 684 | + $var =~ s/\>/>/g; |
| 685 | + $var =~ s/\"/\"/g; |
| 686 | + $var =~ s/\&/\&/g; |
| 687 | + # Now remove extra whitespace... |
| 688 | + my $collapse_filter = $Template::Filters::FILTERS->{collapse}; |
| 689 | + $var = $collapse_filter->($var); |
| 690 | + # And if we're not in the WebService, wrap the message. |
| 691 | + # (Wrapping the message in the WebService is unnecessary |
| 692 | + # and causes awkward things like \n's appearing in error |
| 693 | + # messages in JSON-RPC.) |
| 694 | + unless (Bugzilla->usage_mode == USAGE_MODE_JSON |
| 695 | + or Bugzilla->usage_mode == USAGE_MODE_XMLRPC) |
| 696 | + { |
| 697 | + $var = wrap_comment($var, 72); |
| 698 | + } |
| 699 | + return $var; |
| 700 | + }, |
| 701 | + |
| 702 | + # Wrap a displayed comment to the appropriate length |
| 703 | + wrap_comment => [ |
| 704 | + sub { |
| 705 | + my ($context, $cols) = @_; |
| 706 | + return sub { wrap_comment($_[0], $cols) } |
| 707 | + }, 1], |
| 708 | + |
| 709 | + # We force filtering of every variable in key security-critical |
| 710 | + # places; we have a none filter for people to use when they |
| 711 | + # really, really don't want a variable to be changed. |
| 712 | + none => sub { return $_[0]; } , |
| 713 | + }, |
| 714 | + |
| 715 | + PLUGIN_BASE => 'Bugzilla::Template::Plugin', |
| 716 | + |
| 717 | + CONSTANTS => _load_constants(), |
| 718 | + |
| 719 | + # Default variables for all templates |
| 720 | + VARIABLES => { |
| 721 | + # Function for retrieving global parameters. |
| 722 | + 'Param' => sub { return Bugzilla->params->{$_[0]}; }, |
| 723 | + |
| 724 | + # Function to create date strings |
| 725 | + 'time2str' => \&Date::Format::time2str, |
| 726 | + |
| 727 | + # Generic linear search function |
| 728 | + 'lsearch' => \&Bugzilla::Util::lsearch, |
| 729 | + |
| 730 | + # Currently logged in user, if any |
| 731 | + # If an sudo session is in progress, this is the user we're faking |
| 732 | + 'user' => sub { return Bugzilla->user; }, |
| 733 | + |
| 734 | + # Currenly active language |
| 735 | + # XXX Eventually this should probably be replaced with something |
| 736 | + # like Bugzilla->language. |
| 737 | + 'current_language' => sub { |
| 738 | + my ($language) = include_languages(); |
| 739 | + return $language; |
| 740 | + }, |
| 741 | + |
| 742 | + # If an sudo session is in progress, this is the user who |
| 743 | + # started the session. |
| 744 | + 'sudoer' => sub { return Bugzilla->sudoer; }, |
| 745 | + |
| 746 | + # Allow templates to access the "corect" URLBase value |
| 747 | + 'urlbase' => sub { return Bugzilla::Util::correct_urlbase(); }, |
| 748 | + |
| 749 | + # Allow templates to access docs url with users' preferred language |
| 750 | + 'docs_urlbase' => sub { |
| 751 | + my ($language) = include_languages(); |
| 752 | + my $docs_urlbase = Bugzilla->params->{'docs_urlbase'}; |
| 753 | + $docs_urlbase =~ s/\%lang\%/$language/; |
| 754 | + return $docs_urlbase; |
| 755 | + }, |
| 756 | + |
| 757 | + # Allow templates to generate a token themselves. |
| 758 | + 'issue_hash_token' => \&Bugzilla::Token::issue_hash_token, |
| 759 | + |
| 760 | + # A way for all templates to get at Field data, cached. |
| 761 | + 'bug_fields' => sub { |
| 762 | + my $cache = Bugzilla->request_cache; |
| 763 | + $cache->{template_bug_fields} ||= |
| 764 | + { map { $_->name => $_ } Bugzilla->get_fields() }; |
| 765 | + return $cache->{template_bug_fields}; |
| 766 | + }, |
| 767 | + |
| 768 | + # Whether or not keywords are enabled, in this Bugzilla. |
| 769 | + 'use_keywords' => sub { return Bugzilla::Keyword->any_exist; }, |
| 770 | + |
| 771 | + 'last_bug_list' => sub { |
| 772 | + my @bug_list; |
| 773 | + my $cgi = Bugzilla->cgi; |
| 774 | + if ($cgi->cookie("BUGLIST")) { |
| 775 | + @bug_list = split(/:/, $cgi->cookie("BUGLIST")); |
| 776 | + } |
| 777 | + return \@bug_list; |
| 778 | + }, |
| 779 | + |
| 780 | + 'feature_enabled' => sub { return Bugzilla->feature(@_); }, |
| 781 | + |
| 782 | + # field_descs can be somewhat slow to generate, so we generate |
| 783 | + # it only once per-language no matter how many times |
| 784 | + # $template->process() is called. |
| 785 | + 'field_descs' => sub { return template_var('field_descs') }, |
| 786 | + |
| 787 | + 'install_string' => \&Bugzilla::Install::Util::install_string, |
| 788 | + |
| 789 | + # These don't work as normal constants. |
| 790 | + DB_MODULE => \&Bugzilla::Constants::DB_MODULE, |
| 791 | + REQUIRED_MODULES => |
| 792 | + \&Bugzilla::Install::Requirements::REQUIRED_MODULES, |
| 793 | + OPTIONAL_MODULES => sub { |
| 794 | + my @optional = @{OPTIONAL_MODULES()}; |
| 795 | + foreach my $item (@optional) { |
| 796 | + my @features; |
| 797 | + foreach my $feat_id (@{ $item->{feature} }) { |
| 798 | + push(@features, install_string("feature_$feat_id")); |
| 799 | + } |
| 800 | + $item->{feature} = \@features; |
| 801 | + } |
| 802 | + return \@optional; |
| 803 | + }, |
| 804 | + }, |
| 805 | + }; |
| 806 | + |
| 807 | + local $Template::Config::CONTEXT = 'Bugzilla::Template::Context'; |
| 808 | + |
| 809 | + Bugzilla::Hook::process('template_before_create', { config => $config }); |
| 810 | + my $template = $class->new($config) |
| 811 | + || die("Template creation failed: " . $class->error()); |
| 812 | + return $template; |
| 813 | +} |
| 814 | + |
| 815 | +# Used as part of the two subroutines below. |
| 816 | +our %_templates_to_precompile; |
| 817 | +sub precompile_templates { |
| 818 | + my ($output) = @_; |
| 819 | + |
| 820 | + # Remove the compiled templates. |
| 821 | + my $datadir = bz_locations()->{'datadir'}; |
| 822 | + if (-e "$datadir/template") { |
| 823 | + print install_string('template_removing_dir') . "\n" if $output; |
| 824 | + |
| 825 | + # This frequently fails if the webserver made the files, because |
| 826 | + # then the webserver owns the directories. |
| 827 | + rmtree("$datadir/template"); |
| 828 | + |
| 829 | + # Check that the directory was really removed, and if not, move it |
| 830 | + # into data/deleteme/. |
| 831 | + if (-e "$datadir/template") { |
| 832 | + print STDERR "\n\n", |
| 833 | + install_string('template_removal_failed', |
| 834 | + { datadir => $datadir }), "\n\n"; |
| 835 | + mkpath("$datadir/deleteme"); |
| 836 | + my $random = generate_random_password(); |
| 837 | + rename("$datadir/template", "$datadir/deleteme/$random") |
| 838 | + or die "move failed: $!"; |
| 839 | + } |
| 840 | + } |
| 841 | + |
| 842 | + print install_string('template_precompile') if $output; |
| 843 | + |
| 844 | + my $paths = template_include_path({ use_languages => Bugzilla->languages }); |
| 845 | + |
| 846 | + foreach my $dir (@$paths) { |
| 847 | + my $template = Bugzilla::Template->create(include_path => [$dir]); |
| 848 | + |
| 849 | + %_templates_to_precompile = (); |
| 850 | + # Traverse the template hierarchy. |
| 851 | + find({ wanted => \&_precompile_push, no_chdir => 1 }, $dir); |
| 852 | + # The sort isn't totally necessary, but it makes debugging easier |
| 853 | + # by making the templates always be compiled in the same order. |
| 854 | + foreach my $file (sort keys %_templates_to_precompile) { |
| 855 | + $file =~ s{^\Q$dir\E/}{}; |
| 856 | + # Compile the template but throw away the result. This has the side- |
| 857 | + # effect of writing the compiled version to disk. |
| 858 | + $template->context->template($file); |
| 859 | + } |
| 860 | + } |
| 861 | + |
| 862 | + # Under mod_perl, we look for templates using the absolute path of the |
| 863 | + # template directory, which causes Template Toolkit to look for their |
| 864 | + # *compiled* versions using the full absolute path under the data/template |
| 865 | + # directory. (Like data/template/var/www/html/bugzilla/.) To avoid |
| 866 | + # re-compiling templates under mod_perl, we symlink to the |
| 867 | + # already-compiled templates. This doesn't work on Windows. |
| 868 | + if (!ON_WINDOWS) { |
| 869 | + # We do these separately in case they're in different locations. |
| 870 | + _do_template_symlink(bz_locations()->{'templatedir'}); |
| 871 | + _do_template_symlink(bz_locations()->{'extensionsdir'}); |
| 872 | + } |
| 873 | + |
| 874 | + # If anything created a Template object before now, clear it out. |
| 875 | + delete Bugzilla->request_cache->{template}; |
| 876 | + |
| 877 | + print install_string('done') . "\n" if $output; |
| 878 | +} |
| 879 | + |
| 880 | +# Helper for precompile_templates |
| 881 | +sub _precompile_push { |
| 882 | + my $name = $File::Find::name; |
| 883 | + return if (-d $name); |
| 884 | + return if ($name =~ /\/CVS\//); |
| 885 | + return if ($name !~ /\.tmpl$/); |
| 886 | + $_templates_to_precompile{$name} = 1; |
| 887 | +} |
| 888 | + |
| 889 | +# Helper for precompile_templates |
| 890 | +sub _do_template_symlink { |
| 891 | + my $dir_to_symlink = shift; |
| 892 | + |
| 893 | + my $abs_path = abs_path($dir_to_symlink); |
| 894 | + |
| 895 | + # If $dir_to_symlink is already an absolute path (as might happen |
| 896 | + # with packagers who set $libpath to an absolute path), then we don't |
| 897 | + # need to do this symlink. |
| 898 | + return if ($abs_path eq $dir_to_symlink); |
| 899 | + |
| 900 | + my $abs_root = dirname($abs_path); |
| 901 | + my $dir_name = basename($abs_path); |
| 902 | + my $datadir = bz_locations()->{'datadir'}; |
| 903 | + my $container = "$datadir/template$abs_root"; |
| 904 | + mkpath($container); |
| 905 | + my $target = "$datadir/template/$dir_name"; |
| 906 | + # Check if the directory exists, because if there are no extensions, |
| 907 | + # there won't be an "data/template/extensions" directory to link to. |
| 908 | + if (-d $target) { |
| 909 | + # We use abs2rel so that the symlink will look like |
| 910 | + # "../../../../template" which works, while just |
| 911 | + # "data/template/template/" doesn't work. |
| 912 | + my $relative_target = File::Spec->abs2rel($target, $container); |
| 913 | + |
| 914 | + my $link_name = "$container/$dir_name"; |
| 915 | + symlink($relative_target, $link_name) |
| 916 | + or warn "Could not make $link_name a symlink to $relative_target: $!"; |
| 917 | + } |
| 918 | +} |
| 919 | + |
| 920 | +1; |
| 921 | + |
| 922 | +__END__ |
| 923 | + |
| 924 | +=head1 NAME |
| 925 | + |
| 926 | +Bugzilla::Template - Wrapper around the Template Toolkit C<Template> object |
| 927 | + |
| 928 | +=head1 SYNOPSIS |
| 929 | + |
| 930 | + my $template = Bugzilla::Template->create; |
| 931 | + my $format = $template->get_format("foo/bar", |
| 932 | + scalar($cgi->param('format')), |
| 933 | + scalar($cgi->param('ctype'))); |
| 934 | + |
| 935 | +=head1 DESCRIPTION |
| 936 | + |
| 937 | +This is basically a wrapper so that the correct arguments get passed into |
| 938 | +the C<Template> constructor. |
| 939 | + |
| 940 | +It should not be used directly by scripts or modules - instead, use |
| 941 | +C<Bugzilla-E<gt>instance-E<gt>template> to get an already created module. |
| 942 | + |
| 943 | +=head1 SUBROUTINES |
| 944 | + |
| 945 | +=over |
| 946 | + |
| 947 | +=item C<precompile_templates($output)> |
| 948 | + |
| 949 | +Description: Compiles all of Bugzilla's templates in every language. |
| 950 | + Used mostly by F<checksetup.pl>. |
| 951 | + |
| 952 | +Params: C<$output> - C<true> if you want the function to print |
| 953 | + out information about what it's doing. |
| 954 | + |
| 955 | +Returns: nothing |
| 956 | + |
| 957 | +=back |
| 958 | + |
| 959 | +=head1 METHODS |
| 960 | + |
| 961 | +=over |
| 962 | + |
| 963 | +=item C<get_format($file, $format, $ctype)> |
| 964 | + |
| 965 | + Description: Construct a format object from URL parameters. |
| 966 | + |
| 967 | + Params: $file - Name of the template to display. |
| 968 | + $format - When the template exists under several formats |
| 969 | + (e.g. table or graph), specify the one to choose. |
| 970 | + $ctype - Content type, see Bugzilla::Constants::contenttypes. |
| 971 | + |
| 972 | + Returns: A format object. |
| 973 | + |
| 974 | +=back |
| 975 | + |
| 976 | +=head1 SEE ALSO |
| 977 | + |
| 978 | +L<Bugzilla>, L<Template> |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/Bugzilla/BugMail.pm |
— | — | @@ -0,0 +1,660 @@ |
| 2 | +# -*- Mode: perl; indent-tabs-mode: nil -*- |
| 3 | +# |
| 4 | +# The contents of this file are subject to the Mozilla Public |
| 5 | +# License Version 1.1 (the "License"); you may not use this file |
| 6 | +# except in compliance with the License. You may obtain a copy of |
| 7 | +# the License at http://www.mozilla.org/MPL/ |
| 8 | +# |
| 9 | +# Software distributed under the License is distributed on an "AS |
| 10 | +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 | +# implied. See the License for the specific language governing |
| 12 | +# rights and limitations under the License. |
| 13 | +# |
| 14 | +# The Original Code is the Bugzilla Bug Tracking System. |
| 15 | +# |
| 16 | +# The Initial Developer of the Original Code is Netscape Communications |
| 17 | +# Corporation. Portions created by Netscape are |
| 18 | +# Copyright (C) 1998 Netscape Communications Corporation. All |
| 19 | +# Rights Reserved. |
| 20 | +# |
| 21 | +# Contributor(s): Terry Weissman <terry@mozilla.org>, |
| 22 | +# Bryce Nesbitt <bryce-mozilla@nextbus.com> |
| 23 | +# Dan Mosedale <dmose@mozilla.org> |
| 24 | +# Alan Raetz <al_raetz@yahoo.com> |
| 25 | +# Jacob Steenhagen <jake@actex.net> |
| 26 | +# Matthew Tuck <matty@chariot.net.au> |
| 27 | +# Bradley Baetz <bbaetz@student.usyd.edu.au> |
| 28 | +# J. Paul Reed <preed@sigkill.com> |
| 29 | +# Gervase Markham <gerv@gerv.net> |
| 30 | +# Byron Jones <bugzilla@glob.com.au> |
| 31 | + |
| 32 | +use strict; |
| 33 | + |
| 34 | +package Bugzilla::BugMail; |
| 35 | + |
| 36 | +use Bugzilla::Error; |
| 37 | +use Bugzilla::User; |
| 38 | +use Bugzilla::Constants; |
| 39 | +use Bugzilla::Util; |
| 40 | +use Bugzilla::Bug; |
| 41 | +use Bugzilla::Classification; |
| 42 | +use Bugzilla::Product; |
| 43 | +use Bugzilla::Component; |
| 44 | +use Bugzilla::Status; |
| 45 | +use Bugzilla::Mailer; |
| 46 | +use Bugzilla::Hook; |
| 47 | + |
| 48 | +use Date::Parse; |
| 49 | +use Date::Format; |
| 50 | + |
| 51 | +use constant FORMAT_TRIPLE => "%19s|%-28s|%-28s"; |
| 52 | +use constant FORMAT_3_SIZE => [19,28,28]; |
| 53 | +use constant FORMAT_DOUBLE => "%19s %-55s"; |
| 54 | +use constant FORMAT_2_SIZE => [19,55]; |
| 55 | + |
| 56 | +use constant BIT_DIRECT => 1; |
| 57 | +use constant BIT_WATCHING => 2; |
| 58 | + |
| 59 | +# We need these strings for the X-Bugzilla-Reasons header |
| 60 | +# Note: this hash uses "," rather than "=>" to avoid auto-quoting of the LHS. |
| 61 | +use constant REL_NAMES => { |
| 62 | + REL_ASSIGNEE , "AssignedTo", |
| 63 | + REL_REPORTER , "Reporter", |
| 64 | + REL_QA , "QAcontact", |
| 65 | + REL_CC , "CC", |
| 66 | + REL_VOTER , "Voter", |
| 67 | + REL_GLOBAL_WATCHER, "GlobalWatcher" |
| 68 | +}; |
| 69 | + |
| 70 | +# We use this instead of format because format doesn't deal well with |
| 71 | +# multi-byte languages. |
| 72 | +sub multiline_sprintf { |
| 73 | + my ($format, $args, $sizes) = @_; |
| 74 | + my @parts; |
| 75 | + my @my_sizes = @$sizes; # Copy this so we don't modify the input array. |
| 76 | + foreach my $string (@$args) { |
| 77 | + my $size = shift @my_sizes; |
| 78 | + my @pieces = split("\n", wrap_hard($string, $size)); |
| 79 | + push(@parts, \@pieces); |
| 80 | + } |
| 81 | + |
| 82 | + my $formatted; |
| 83 | + while (1) { |
| 84 | + # Get the first item of each part. |
| 85 | + my @line = map { shift @$_ } @parts; |
| 86 | + # If they're all undef, we're done. |
| 87 | + last if !grep { defined $_ } @line; |
| 88 | + # Make any single undef item into '' |
| 89 | + @line = map { defined $_ ? $_ : '' } @line; |
| 90 | + # And append a formatted line |
| 91 | + $formatted .= sprintf($format, @line); |
| 92 | + # Remove trailing spaces, or they become lots of =20's in |
| 93 | + # quoted-printable emails. |
| 94 | + $formatted =~ s/\s+$//; |
| 95 | + $formatted .= "\n"; |
| 96 | + } |
| 97 | + return $formatted; |
| 98 | +} |
| 99 | + |
| 100 | +sub three_columns { |
| 101 | + return multiline_sprintf(FORMAT_TRIPLE, \@_, FORMAT_3_SIZE); |
| 102 | +} |
| 103 | + |
| 104 | +# This is a bit of a hack, basically keeping the old system() |
| 105 | +# cmd line interface. Should clean this up at some point. |
| 106 | +# |
| 107 | +# args: bug_id, and an optional hash ref which may have keys for: |
| 108 | +# changer, owner, qa, reporter, cc |
| 109 | +# Optional hash contains values of people which will be forced to those |
| 110 | +# roles when the email is sent. |
| 111 | +# All the names are email addresses, not userids |
| 112 | +# values are scalars, except for cc, which is a list |
| 113 | +sub Send { |
| 114 | + my ($id, $forced) = (@_); |
| 115 | + |
| 116 | + my @headerlist; |
| 117 | + my %defmailhead; |
| 118 | + my %fielddescription; |
| 119 | + |
| 120 | + my $msg = ""; |
| 121 | + |
| 122 | + my $dbh = Bugzilla->dbh; |
| 123 | + my $bug = new Bugzilla::Bug($id); |
| 124 | + |
| 125 | + # XXX - These variables below are useless. We could use field object |
| 126 | + # methods directly. But we first have to implement a cache in |
| 127 | + # Bugzilla->get_fields to avoid querying the DB all the time. |
| 128 | + foreach my $field (Bugzilla->get_fields({obsolete => 0})) { |
| 129 | + push(@headerlist, $field->name); |
| 130 | + $defmailhead{$field->name} = $field->in_new_bugmail; |
| 131 | + $fielddescription{$field->name} = $field->description; |
| 132 | + } |
| 133 | + |
| 134 | + my %values = %{$dbh->selectrow_hashref( |
| 135 | + 'SELECT ' . join(',', editable_bug_fields()) . ', reporter, |
| 136 | + lastdiffed AS start_time, LOCALTIMESTAMP(0) AS end_time |
| 137 | + FROM bugs WHERE bug_id = ?', |
| 138 | + undef, $id)}; |
| 139 | + |
| 140 | + my $product = new Bugzilla::Product($values{product_id}); |
| 141 | + $values{product} = $product->name; |
| 142 | + if (Bugzilla->params->{'useclassification'}) { |
| 143 | + $values{classification} = Bugzilla::Classification->new($product->classification_id)->name; |
| 144 | + } |
| 145 | + my $component = new Bugzilla::Component($values{component_id}); |
| 146 | + $values{component} = $component->name; |
| 147 | + |
| 148 | + my ($start, $end) = ($values{start_time}, $values{end_time}); |
| 149 | + |
| 150 | + # User IDs of people in various roles. More than one person can 'have' a |
| 151 | + # role, if the person in that role has changed, or people are watching. |
| 152 | + my $reporter = $values{'reporter'}; |
| 153 | + my @assignees = ($values{'assigned_to'}); |
| 154 | + my @qa_contacts = ($values{'qa_contact'}); |
| 155 | + |
| 156 | + my $cc_users = $dbh->selectall_arrayref( |
| 157 | + "SELECT cc.who, profiles.login_name |
| 158 | + FROM cc |
| 159 | + INNER JOIN profiles |
| 160 | + ON cc.who = profiles.userid |
| 161 | + WHERE bug_id = ?", |
| 162 | + undef, $id); |
| 163 | + |
| 164 | + my (@ccs, @cc_login_names); |
| 165 | + foreach my $cc_user (@$cc_users) { |
| 166 | + my ($user_id, $user_login) = @$cc_user; |
| 167 | + push (@ccs, $user_id); |
| 168 | + push (@cc_login_names, $user_login); |
| 169 | + } |
| 170 | + |
| 171 | + # Include the people passed in as being in particular roles. |
| 172 | + # This can include people who used to hold those roles. |
| 173 | + # At this point, we don't care if there are duplicates in these arrays. |
| 174 | + my $changer = $forced->{'changer'}; |
| 175 | + if ($forced->{'owner'}) { |
| 176 | + push (@assignees, login_to_id($forced->{'owner'}, THROW_ERROR)); |
| 177 | + } |
| 178 | + |
| 179 | + if ($forced->{'qacontact'}) { |
| 180 | + push (@qa_contacts, login_to_id($forced->{'qacontact'}, THROW_ERROR)); |
| 181 | + } |
| 182 | + |
| 183 | + if ($forced->{'cc'}) { |
| 184 | + foreach my $cc (@{$forced->{'cc'}}) { |
| 185 | + push(@ccs, login_to_id($cc, THROW_ERROR)); |
| 186 | + } |
| 187 | + } |
| 188 | + |
| 189 | + # Convert to names, for later display |
| 190 | + $values{'changer'} = $changer; |
| 191 | + # If no changer is specified, then it has no name. |
| 192 | + if ($changer) { |
| 193 | + $values{'changername'} = Bugzilla::User->new({name => $changer})->name; |
| 194 | + } |
| 195 | + $values{'assigned_to'} = user_id_to_login($values{'assigned_to'}); |
| 196 | + $values{'reporter'} = user_id_to_login($values{'reporter'}); |
| 197 | + if ($values{'qa_contact'}) { |
| 198 | + $values{'qa_contact'} = user_id_to_login($values{'qa_contact'}); |
| 199 | + } |
| 200 | + $values{'cc'} = join(', ', @cc_login_names); |
| 201 | + $values{'estimated_time'} = format_time_decimal($values{'estimated_time'}); |
| 202 | + |
| 203 | + if ($values{'deadline'}) { |
| 204 | + $values{'deadline'} = time2str("%Y-%m-%d", str2time($values{'deadline'})); |
| 205 | + } |
| 206 | + |
| 207 | + my $dependslist = $dbh->selectcol_arrayref( |
| 208 | + 'SELECT dependson FROM dependencies |
| 209 | + WHERE blocked = ? ORDER BY dependson', |
| 210 | + undef, ($id)); |
| 211 | + |
| 212 | + $values{'dependson'} = join(",", @$dependslist); |
| 213 | + |
| 214 | + my $blockedlist = $dbh->selectcol_arrayref( |
| 215 | + 'SELECT blocked FROM dependencies |
| 216 | + WHERE dependson = ? ORDER BY blocked', |
| 217 | + undef, ($id)); |
| 218 | + |
| 219 | + $values{'blocked'} = join(",", @$blockedlist); |
| 220 | + |
| 221 | + my $grouplist = $dbh->selectcol_arrayref( |
| 222 | + ' SELECT name FROM groups |
| 223 | + INNER JOIN bug_group_map |
| 224 | + ON groups.id = bug_group_map.group_id |
| 225 | + AND bug_group_map.bug_id = ?', |
| 226 | + undef, ($id)); |
| 227 | + |
| 228 | + $values{'bug_group'} = join(', ', @$grouplist); |
| 229 | + |
| 230 | + my @args = ($id); |
| 231 | + |
| 232 | + # If lastdiffed is NULL, then we don't limit the search on time. |
| 233 | + my $when_restriction = ''; |
| 234 | + if ($start) { |
| 235 | + $when_restriction = ' AND bug_when > ? AND bug_when <= ?'; |
| 236 | + push @args, ($start, $end); |
| 237 | + } |
| 238 | + |
| 239 | + my $diffs = $dbh->selectall_arrayref( |
| 240 | + "SELECT profiles.login_name, profiles.realname, fielddefs.description, |
| 241 | + bugs_activity.bug_when, bugs_activity.removed, |
| 242 | + bugs_activity.added, bugs_activity.attach_id, fielddefs.name |
| 243 | + FROM bugs_activity |
| 244 | + INNER JOIN fielddefs |
| 245 | + ON fielddefs.id = bugs_activity.fieldid |
| 246 | + INNER JOIN profiles |
| 247 | + ON profiles.userid = bugs_activity.who |
| 248 | + WHERE bugs_activity.bug_id = ? |
| 249 | + $when_restriction |
| 250 | + ORDER BY bugs_activity.bug_when", undef, @args); |
| 251 | + |
| 252 | + my @new_depbugs; |
| 253 | + my $difftext = ""; |
| 254 | + my $diffheader = ""; |
| 255 | + my @diffparts; |
| 256 | + my $lastwho = ""; |
| 257 | + my $fullwho; |
| 258 | + my @changedfields; |
| 259 | + foreach my $ref (@$diffs) { |
| 260 | + my ($who, $whoname, $what, $when, $old, $new, $attachid, $fieldname) = (@$ref); |
| 261 | + my $diffpart = {}; |
| 262 | + if ($who ne $lastwho) { |
| 263 | + $lastwho = $who; |
| 264 | + $fullwho = $whoname ? "$whoname <$who>" : $who; |
| 265 | + $diffheader = "\n$fullwho changed:\n\n"; |
| 266 | + $diffheader .= three_columns("What ", "Removed", "Added"); |
| 267 | + $diffheader .= ('-' x 76) . "\n"; |
| 268 | + } |
| 269 | + $what =~ s/^(Attachment )?/Attachment #$attachid / if $attachid; |
| 270 | + if( $fieldname eq 'estimated_time' || |
| 271 | + $fieldname eq 'remaining_time' ) { |
| 272 | + $old = format_time_decimal($old); |
| 273 | + $new = format_time_decimal($new); |
| 274 | + } |
| 275 | + if ($fieldname eq 'dependson') { |
| 276 | + push(@new_depbugs, grep {$_ =~ /^\d+$/} split(/[\s,]+/, $new)); |
| 277 | + } |
| 278 | + if ($attachid) { |
| 279 | + ($diffpart->{'isprivate'}) = $dbh->selectrow_array( |
| 280 | + 'SELECT isprivate FROM attachments WHERE attach_id = ?', |
| 281 | + undef, ($attachid)); |
| 282 | + } |
| 283 | + $difftext = three_columns($what, $old, $new); |
| 284 | + $diffpart->{'header'} = $diffheader; |
| 285 | + $diffpart->{'fieldname'} = $fieldname; |
| 286 | + $diffpart->{'text'} = $difftext; |
| 287 | + push(@diffparts, $diffpart); |
| 288 | + push(@changedfields, $what); |
| 289 | + } |
| 290 | + $values{'changed_fields'} = join(' ', @changedfields); |
| 291 | + |
| 292 | + my @depbugs; |
| 293 | + my $deptext = ""; |
| 294 | + # Do not include data about dependent bugs when they have just been added. |
| 295 | + # Completely skip checking for dependent bugs on bug creation as all |
| 296 | + # dependencies bugs will just have been added. |
| 297 | + if ($start) { |
| 298 | + my $dep_restriction = ""; |
| 299 | + if (scalar @new_depbugs) { |
| 300 | + $dep_restriction = "AND bugs_activity.bug_id NOT IN (" . |
| 301 | + join(", ", @new_depbugs) . ")"; |
| 302 | + } |
| 303 | + |
| 304 | + my $dependency_diffs = $dbh->selectall_arrayref( |
| 305 | + "SELECT bugs_activity.bug_id, bugs.short_desc, fielddefs.name, |
| 306 | + bugs_activity.removed, bugs_activity.added |
| 307 | + FROM bugs_activity |
| 308 | + INNER JOIN bugs |
| 309 | + ON bugs.bug_id = bugs_activity.bug_id |
| 310 | + INNER JOIN dependencies |
| 311 | + ON bugs_activity.bug_id = dependencies.dependson |
| 312 | + INNER JOIN fielddefs |
| 313 | + ON fielddefs.id = bugs_activity.fieldid |
| 314 | + WHERE dependencies.blocked = ? |
| 315 | + AND (fielddefs.name = 'bug_status' |
| 316 | + OR fielddefs.name = 'resolution') |
| 317 | + $when_restriction |
| 318 | + $dep_restriction |
| 319 | + ORDER BY bugs_activity.bug_when, bugs.bug_id", undef, @args); |
| 320 | + |
| 321 | + my $thisdiff = ""; |
| 322 | + my $lastbug = ""; |
| 323 | + my $interestingchange = 0; |
| 324 | + foreach my $dependency_diff (@$dependency_diffs) { |
| 325 | + my ($depbug, $summary, $what, $old, $new) = @$dependency_diff; |
| 326 | + |
| 327 | + if ($depbug ne $lastbug) { |
| 328 | + if ($interestingchange) { |
| 329 | + $deptext .= $thisdiff; |
| 330 | + } |
| 331 | + $lastbug = $depbug; |
| 332 | + $thisdiff = |
| 333 | + "\nBug $id depends on bug $depbug, which changed state.\n\n" . |
| 334 | + "Bug $depbug Summary: $summary\n" . |
| 335 | + correct_urlbase() . "show_bug.cgi?id=$depbug\n\n"; |
| 336 | + $thisdiff .= three_columns("What ", "Old Value", "New Value"); |
| 337 | + $thisdiff .= ('-' x 76) . "\n"; |
| 338 | + $interestingchange = 0; |
| 339 | + } |
| 340 | + $thisdiff .= three_columns($fielddescription{$what}, $old, $new); |
| 341 | + if ($what eq 'bug_status' |
| 342 | + && is_open_state($old) ne is_open_state($new)) |
| 343 | + { |
| 344 | + $interestingchange = 1; |
| 345 | + } |
| 346 | + push(@depbugs, $depbug); |
| 347 | + } |
| 348 | + |
| 349 | + if ($interestingchange) { |
| 350 | + $deptext .= $thisdiff; |
| 351 | + } |
| 352 | + $deptext = trim($deptext); |
| 353 | + |
| 354 | + if ($deptext) { |
| 355 | + my $diffpart = {}; |
| 356 | + $diffpart->{'text'} = "\n" . trim($deptext); |
| 357 | + push(@diffparts, $diffpart); |
| 358 | + } |
| 359 | + } |
| 360 | + |
| 361 | + my $comments = $bug->comments({ after => $start, to => $end }); |
| 362 | + |
| 363 | + ########################################################################### |
| 364 | + # Start of email filtering code |
| 365 | + ########################################################################### |
| 366 | + |
| 367 | + # A user_id => roles hash to keep track of people. |
| 368 | + my %recipients; |
| 369 | + my %watching; |
| 370 | + |
| 371 | + # Now we work out all the people involved with this bug, and note all of |
| 372 | + # the relationships in a hash. The keys are userids, the values are an |
| 373 | + # array of role constants. |
| 374 | + |
| 375 | + # Voters |
| 376 | + my $voters = $dbh->selectcol_arrayref( |
| 377 | + "SELECT who FROM votes WHERE bug_id = ?", undef, ($id)); |
| 378 | + |
| 379 | + $recipients{$_}->{+REL_VOTER} = BIT_DIRECT foreach (@$voters); |
| 380 | + |
| 381 | + # CCs |
| 382 | + $recipients{$_}->{+REL_CC} = BIT_DIRECT foreach (@ccs); |
| 383 | + |
| 384 | + # Reporter (there's only ever one) |
| 385 | + $recipients{$reporter}->{+REL_REPORTER} = BIT_DIRECT; |
| 386 | + |
| 387 | + # QA Contact |
| 388 | + if (Bugzilla->params->{'useqacontact'}) { |
| 389 | + foreach (@qa_contacts) { |
| 390 | + # QA Contact can be blank; ignore it if so. |
| 391 | + $recipients{$_}->{+REL_QA} = BIT_DIRECT if $_; |
| 392 | + } |
| 393 | + } |
| 394 | + |
| 395 | + # Assignee |
| 396 | + $recipients{$_}->{+REL_ASSIGNEE} = BIT_DIRECT foreach (@assignees); |
| 397 | + |
| 398 | + # The last relevant set of people are those who are being removed from |
| 399 | + # their roles in this change. We get their names out of the diffs. |
| 400 | + foreach my $ref (@$diffs) { |
| 401 | + my ($who, $whoname, $what, $when, $old, $new) = (@$ref); |
| 402 | + if ($old) { |
| 403 | + # You can't stop being the reporter, and mail isn't sent if you |
| 404 | + # remove your vote. |
| 405 | + # Ignore people whose user account has been deleted or renamed. |
| 406 | + if ($what eq "CC") { |
| 407 | + foreach my $cc_user (split(/[\s,]+/, $old)) { |
| 408 | + my $uid = login_to_id($cc_user); |
| 409 | + $recipients{$uid}->{+REL_CC} = BIT_DIRECT if $uid; |
| 410 | + } |
| 411 | + } |
| 412 | + elsif ($what eq "QAContact") { |
| 413 | + my $uid = login_to_id($old); |
| 414 | + $recipients{$uid}->{+REL_QA} = BIT_DIRECT if $uid; |
| 415 | + } |
| 416 | + elsif ($what eq "AssignedTo") { |
| 417 | + my $uid = login_to_id($old); |
| 418 | + $recipients{$uid}->{+REL_ASSIGNEE} = BIT_DIRECT if $uid; |
| 419 | + } |
| 420 | + } |
| 421 | + } |
| 422 | + |
| 423 | + Bugzilla::Hook::process('bugmail_recipients', |
| 424 | + { bug => $bug, recipients => \%recipients }); |
| 425 | + |
| 426 | + # Find all those user-watching anyone on the current list, who is not |
| 427 | + # on it already themselves. |
| 428 | + my $involved = join(",", keys %recipients); |
| 429 | + |
| 430 | + my $userwatchers = |
| 431 | + $dbh->selectall_arrayref("SELECT watcher, watched FROM watch |
| 432 | + WHERE watched IN ($involved)"); |
| 433 | + |
| 434 | + # Mark these people as having the role of the person they are watching |
| 435 | + foreach my $watch (@$userwatchers) { |
| 436 | + while (my ($role, $bits) = each %{$recipients{$watch->[1]}}) { |
| 437 | + $recipients{$watch->[0]}->{$role} |= BIT_WATCHING |
| 438 | + if $bits & BIT_DIRECT; |
| 439 | + } |
| 440 | + push(@{$watching{$watch->[0]}}, $watch->[1]); |
| 441 | + } |
| 442 | + |
| 443 | + # Global watcher |
| 444 | + my @watchers = split(/[,\s]+/, Bugzilla->params->{'globalwatchers'}); |
| 445 | + foreach (@watchers) { |
| 446 | + my $watcher_id = login_to_id($_); |
| 447 | + next unless $watcher_id; |
| 448 | + #$recipients{$watcher_id}->{+REL_GLOBAL_WATCHER} = BIT_DIRECT; |
| 449 | + # Hack! Pretend global watchers are CCs so we can use their prefs |
| 450 | + # to for instance ignore CC-only mails. |
| 451 | + $recipients{$watcher_id}->{+REL_CC} = BIT_DIRECT; |
| 452 | + } |
| 453 | + |
| 454 | + # We now have a complete set of all the users, and their relationships to |
| 455 | + # the bug in question. However, we are not necessarily going to mail them |
| 456 | + # all - there are preferences, permissions checks and all sorts to do yet. |
| 457 | + my @sent; |
| 458 | + my @excluded; |
| 459 | + |
| 460 | + foreach my $user_id (keys %recipients) { |
| 461 | + my %rels_which_want; |
| 462 | + my $sent_mail = 0; |
| 463 | + |
| 464 | + my $user = new Bugzilla::User($user_id); |
| 465 | + # Deleted users must be excluded. |
| 466 | + next unless $user; |
| 467 | + |
| 468 | + if ($user->can_see_bug($id)) { |
| 469 | + # Go through each role the user has and see if they want mail in |
| 470 | + # that role. |
| 471 | + foreach my $relationship (keys %{$recipients{$user_id}}) { |
| 472 | + if ($user->wants_bug_mail($id, |
| 473 | + $relationship, |
| 474 | + $diffs, |
| 475 | + $comments, |
| 476 | + $deptext, |
| 477 | + $changer, |
| 478 | + !$start)) |
| 479 | + { |
| 480 | + $rels_which_want{$relationship} = |
| 481 | + $recipients{$user_id}->{$relationship}; |
| 482 | + } |
| 483 | + } |
| 484 | + } |
| 485 | + |
| 486 | + if (scalar(%rels_which_want)) { |
| 487 | + # So the user exists, can see the bug, and wants mail in at least |
| 488 | + # one role. But do we want to send it to them? |
| 489 | + |
| 490 | + # We shouldn't send mail if this is a dependency mail (i.e. there |
| 491 | + # is something in @depbugs), and any of the depending bugs are not |
| 492 | + # visible to the user. This is to avoid leaking the summaries of |
| 493 | + # confidential bugs. |
| 494 | + my $dep_ok = 1; |
| 495 | + foreach my $dep_id (@depbugs) { |
| 496 | + if (!$user->can_see_bug($dep_id)) { |
| 497 | + $dep_ok = 0; |
| 498 | + last; |
| 499 | + } |
| 500 | + } |
| 501 | + |
| 502 | + # Make sure the user isn't in the nomail list, and the insider and |
| 503 | + # dep checks passed. |
| 504 | + if ($user->email_enabled && $dep_ok) { |
| 505 | + # OK, OK, if we must. Email the user. |
| 506 | + $sent_mail = sendMail($user, |
| 507 | + \@headerlist, |
| 508 | + \%rels_which_want, |
| 509 | + \%values, |
| 510 | + \%defmailhead, |
| 511 | + \%fielddescription, |
| 512 | + \@diffparts, |
| 513 | + $comments, |
| 514 | + ! $start, |
| 515 | + $id, |
| 516 | + exists $watching{$user_id} ? |
| 517 | + $watching{$user_id} : undef); |
| 518 | + } |
| 519 | + } |
| 520 | + |
| 521 | + if ($sent_mail) { |
| 522 | + push(@sent, $user->login); |
| 523 | + } |
| 524 | + else { |
| 525 | + push(@excluded, $user->login); |
| 526 | + } |
| 527 | + } |
| 528 | + |
| 529 | + $dbh->do('UPDATE bugs SET lastdiffed = ? WHERE bug_id = ?', |
| 530 | + undef, ($end, $id)); |
| 531 | + |
| 532 | + return {'sent' => \@sent, 'excluded' => \@excluded}; |
| 533 | +} |
| 534 | + |
| 535 | +sub sendMail { |
| 536 | + my ($user, $hlRef, $relRef, $valueRef, $dmhRef, $fdRef, |
| 537 | + $diffRef, $comments_in, $isnew, $id, $watchingRef) = @_; |
| 538 | + |
| 539 | + my @send_comments = @$comments_in; |
| 540 | + my %values = %$valueRef; |
| 541 | + my @headerlist = @$hlRef; |
| 542 | + my %mailhead = %$dmhRef; |
| 543 | + my %fielddescription = %$fdRef; |
| 544 | + my @diffparts = @$diffRef; |
| 545 | + |
| 546 | + # Build difftext (the actions) by verifying the user should see them |
| 547 | + my $difftext = ""; |
| 548 | + my $diffheader = ""; |
| 549 | + my $add_diff; |
| 550 | + |
| 551 | + foreach my $diff (@diffparts) { |
| 552 | + $add_diff = 0; |
| 553 | + |
| 554 | + if (exists($diff->{'fieldname'}) && |
| 555 | + ($diff->{'fieldname'} eq 'estimated_time' || |
| 556 | + $diff->{'fieldname'} eq 'remaining_time' || |
| 557 | + $diff->{'fieldname'} eq 'work_time' || |
| 558 | + $diff->{'fieldname'} eq 'deadline')) |
| 559 | + { |
| 560 | + $add_diff = 1 if $user->is_timetracker; |
| 561 | + } elsif ($diff->{'isprivate'} |
| 562 | + && !$user->is_insider) |
| 563 | + { |
| 564 | + $add_diff = 0; |
| 565 | + } else { |
| 566 | + $add_diff = 1; |
| 567 | + } |
| 568 | + |
| 569 | + if ($add_diff) { |
| 570 | + if (exists($diff->{'header'}) && |
| 571 | + ($diffheader ne $diff->{'header'})) { |
| 572 | + $diffheader = $diff->{'header'}; |
| 573 | + $difftext .= $diffheader; |
| 574 | + } |
| 575 | + $difftext .= $diff->{'text'}; |
| 576 | + } |
| 577 | + } |
| 578 | + |
| 579 | + if (!$user->is_insider) { |
| 580 | + @send_comments = grep { !$_->is_private } @send_comments; |
| 581 | + } |
| 582 | + |
| 583 | + if ($difftext eq "" && !scalar(@send_comments) && !$isnew) { |
| 584 | + # Whoops, no differences! |
| 585 | + return 0; |
| 586 | + } |
| 587 | + |
| 588 | + my $diffs = $difftext; |
| 589 | + # Remove extra newlines. |
| 590 | + $diffs =~ s/^\n+//s; $diffs =~ s/\n+$//s; |
| 591 | + if ($isnew) { |
| 592 | + my $head = ""; |
| 593 | + foreach my $f (@headerlist) { |
| 594 | + next unless $mailhead{$f}; |
| 595 | + my $value = $values{$f}; |
| 596 | + # If there isn't anything to show, don't include this header. |
| 597 | + next unless $value; |
| 598 | + # Only send estimated_time if it is enabled and the user is in the group. |
| 599 | + if (($f ne 'estimated_time' && $f ne 'deadline') || $user->is_timetracker) { |
| 600 | + my $desc = $fielddescription{$f}; |
| 601 | + $head .= multiline_sprintf(FORMAT_DOUBLE, ["$desc:", $value], |
| 602 | + FORMAT_2_SIZE); |
| 603 | + } |
| 604 | + } |
| 605 | + $diffs = $head . ($difftext ? "\n\n" : "") . $diffs; |
| 606 | + } |
| 607 | + |
| 608 | + my (@reasons, @reasons_watch); |
| 609 | + while (my ($relationship, $bits) = each %{$relRef}) { |
| 610 | + push(@reasons, $relationship) if ($bits & BIT_DIRECT); |
| 611 | + push(@reasons_watch, $relationship) if ($bits & BIT_WATCHING); |
| 612 | + } |
| 613 | + |
| 614 | + my @headerrel = map { REL_NAMES->{$_} } @reasons; |
| 615 | + my @watchingrel = map { REL_NAMES->{$_} } @reasons_watch; |
| 616 | + push(@headerrel, 'None') unless @headerrel; |
| 617 | + push(@watchingrel, 'None') unless @watchingrel; |
| 618 | + push @watchingrel, map { user_id_to_login($_) } @$watchingRef; |
| 619 | + |
| 620 | + my $vars = { |
| 621 | + isnew => $isnew, |
| 622 | + to_user => $user, |
| 623 | + bugid => $id, |
| 624 | + alias => Bugzilla->params->{'usebugaliases'} ? $values{'alias'} : "", |
| 625 | + classification => $values{'classification'}, |
| 626 | + product => $values{'product'}, |
| 627 | + comp => $values{'component'}, |
| 628 | + keywords => $values{'keywords'}, |
| 629 | + severity => $values{'bug_severity'}, |
| 630 | + status => $values{'bug_status'}, |
| 631 | + priority => $values{'priority'}, |
| 632 | + assignedto => $values{'assigned_to'}, |
| 633 | + assignedtoname => Bugzilla::User->new({name => $values{'assigned_to'}})->name, |
| 634 | + targetmilestone => $values{'target_milestone'}, |
| 635 | + changedfields => $values{'changed_fields'}, |
| 636 | + summary => $values{'short_desc'}, |
| 637 | + reasons => \@reasons, |
| 638 | + reasons_watch => \@reasons_watch, |
| 639 | + reasonsheader => join(" ", @headerrel), |
| 640 | + reasonswatchheader => join(" ", @watchingrel), |
| 641 | + changer => $values{'changer'}, |
| 642 | + changername => $values{'changername'}, |
| 643 | + reporter => $values{'reporter'}, |
| 644 | + reportername => Bugzilla::User->new({name => $values{'reporter'}})->name, |
| 645 | + diffs => $diffs, |
| 646 | + new_comments => \@send_comments, |
| 647 | + threadingmarker => build_thread_marker($id, $user->id, $isnew), |
| 648 | + }; |
| 649 | + |
| 650 | + my $msg; |
| 651 | + my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'}); |
| 652 | + $template->process("email/newchangedmail.txt.tmpl", $vars, \$msg) |
| 653 | + || ThrowTemplateError($template->error()); |
| 654 | + Bugzilla->template_inner(""); |
| 655 | + |
| 656 | + MessageToMTA($msg); |
| 657 | + |
| 658 | + return 1; |
| 659 | +} |
| 660 | + |
| 661 | +1; |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/global/site-navigation.html.tmpl |
— | — | @@ -0,0 +1,127 @@ |
| 2 | +[%# The contents of this file are subject to the Mozilla Public |
| 3 | + # License Version 1.1 (the "License"); you may not use this file |
| 4 | + # except in compliance with the License. You may obtain a copy of |
| 5 | + # the License at http://www.mozilla.org/MPL/ |
| 6 | + # |
| 7 | + # Software distributed under the License is distributed on an "AS |
| 8 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + # implied. See the License for the specific language governing |
| 10 | + # rights and limitations under the License. |
| 11 | + # |
| 12 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + # |
| 14 | + # The Initial Developer of the Original Code is Netscape Communications |
| 15 | + # Corporation. Portions created by Netscape are |
| 16 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + # Rights Reserved. |
| 18 | + # |
| 19 | + # Contributor(s): Toms Baugis <toms.baugis@tietoenator.com> |
| 20 | + # Gervase Markham <gerv@gerv.net> |
| 21 | + #%] |
| 22 | + |
| 23 | +[%# INTERFACE: |
| 24 | + # bug_list: list of integers. List of bug numbers of current query (if any). |
| 25 | + # bug.bug_id: integer. Number of current bug (for navigation purposes) |
| 26 | + #%] |
| 27 | + |
| 28 | +[% PROCESS global/variables.none.tmpl %] |
| 29 | + |
| 30 | +[% USE Bugzilla %] |
| 31 | +[% cgi = Bugzilla.cgi %] |
| 32 | + |
| 33 | +[% IF NOT (cgi.user_agent("MSIE [1-6]") OR cgi.user_agent("Mozilla/4")) %] |
| 34 | + <link rel="Top" href="[% urlbase FILTER html %]"> |
| 35 | + |
| 36 | + [%# *** Bug List Navigation *** %] |
| 37 | + [% IF bug_list && bug_list.size > 0 %] |
| 38 | + <link rel="Up" href="buglist.cgi?regetlastlist=1"> |
| 39 | + |
| 40 | + <link rel="First" href="show_bug.cgi?id=[% bug_list.first %]"> |
| 41 | + <link rel="Last" href="show_bug.cgi?id=[% bug_list.last %]"> |
| 42 | + |
| 43 | + [% IF bug && bug.bug_id %] |
| 44 | + [% current_bug_idx = lsearch(bug_list, bug.bug_id) %] |
| 45 | + [% IF current_bug_idx != -1 %] |
| 46 | + |
| 47 | + [% IF current_bug_idx > 0 %] |
| 48 | + [% prev_bug = current_bug_idx - 1 %] |
| 49 | + <link rel="Prev" href="show_bug.cgi?id=[% bug_list.$prev_bug %]"> |
| 50 | + [% END %] |
| 51 | + |
| 52 | + [% IF current_bug_idx + 1 < bug_list.size %] |
| 53 | + [% next_bug = current_bug_idx + 1 %] |
| 54 | + <link rel="Next" href="show_bug.cgi?id=[% bug_list.$next_bug %]"> |
| 55 | + [% END %] |
| 56 | + |
| 57 | + [% END %] |
| 58 | + [% END %] |
| 59 | + [% END %] |
| 60 | + |
| 61 | + [%# *** Attachment *** %] |
| 62 | + [% IF attachment && attachment.bug_id %] |
| 63 | + <link rel="Up" href="show_bug.cgi?id=[% attachment.bug_id FILTER none %]"> |
| 64 | + [% END %] |
| 65 | + |
| 66 | + |
| 67 | + [%# *** Dependencies, Votes, Activity, Print-version *** %] |
| 68 | + [% IF bug %] |
| 69 | + <link rel="Show" title="Dependency Tree" |
| 70 | + href="showdependencytree.cgi?id=[% bug.bug_id %]&hide_resolved=1"> |
| 71 | + [% IF Param('webdotbase') %] |
| 72 | + <link rel="Show" title="Dependency Graph" |
| 73 | + href="showdependencygraph.cgi?id=[% bug.bug_id %]"> |
| 74 | + [% END %] |
| 75 | + |
| 76 | + [% IF bug.use_votes %] |
| 77 | + <link rel="Show" title="Votes ([% bug.votes %])" |
| 78 | + href="votes.cgi?action=show_bug&bug_id=[% bug.bug_id %]"> |
| 79 | + [% END %] |
| 80 | + |
| 81 | + <link rel="Show" title="[% terms.Bug %] Activity" |
| 82 | + href="show_activity.cgi?id=[% bug.bug_id %]"> |
| 83 | + <link rel="Show" title="Printer-Friendly Version" |
| 84 | + href="show_bug.cgi?format=multiple&id=[% bug.bug_id %]"> |
| 85 | + [% END %] |
| 86 | + |
| 87 | + |
| 88 | + [%# *** Saved Searches *** %] |
| 89 | + [% IF user.showmybugslink %] |
| 90 | + [% user_login = user.login FILTER url_quote %] |
| 91 | + <link rel="Saved Searches" title="My [% terms.Bugs %]" |
| 92 | + href="[% Param('mybugstemplate').replace('%userid%', user_login) %]"> |
| 93 | + [% END %] |
| 94 | + |
| 95 | + [% FOREACH q = user.queries %] |
| 96 | + <link rel="Saved Searches" |
| 97 | + title="[% q.name FILTER html %]" |
| 98 | + href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]"> |
| 99 | + [% END %] |
| 100 | + |
| 101 | + [% FOREACH q = user.queries_subscribed %] |
| 102 | + <link rel="Saved Search" |
| 103 | + title="[% q.name FILTER html %] ([% q.user.login FILTER html %])" |
| 104 | + href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd= |
| 105 | + [% q.name FILTER url_quote %]&sharer_id= |
| 106 | + [% q.user.id FILTER url_quote %]"> |
| 107 | + [% END %] |
| 108 | + |
| 109 | + [%# *** Bugzilla Administration Tools *** %] |
| 110 | + [% IF user.login %] |
| 111 | + [% '<link rel="Administration" title="Parameters" |
| 112 | + href="editparams.cgi">' IF user.in_group('tweakparams') %] |
| 113 | + [% '<link rel="Administration" title="Users" |
| 114 | + href="editusers.cgi">' IF user.in_group('editusers') %] |
| 115 | + [% '<link rel="Administration" title="Products" href="editproducts.cgi">' |
| 116 | + IF user.in_group('editcomponents') || user.get_products_by_permission("editcomponents").size %] |
| 117 | + [% '<link rel="Administration" title="Flag Types" |
| 118 | + href="editflagtypes.cgi">' IF user.in_group('editcomponents') %] |
| 119 | + [% '<link rel="Administration" title="Groups" |
| 120 | + href="editgroups.cgi">' IF user.in_group('creategroups') %] |
| 121 | + [% '<link rel="Administration" title="Keywords" |
| 122 | + href="editkeywords.cgi">' IF user.in_group('editkeywords') %] |
| 123 | + [% '<link rel="Administration" title="Whining" |
| 124 | + href="editwhines.cgi">' IF user.in_group('bz_canusewhines') %] |
| 125 | + [% '<link rel="Administration" title="Sanity Check" |
| 126 | + href="sanitycheck.cgi">' IF user.in_group('editcomponents') %] |
| 127 | + [% END %] |
| 128 | +[% END %] |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/global/nav-links.html.tmpl |
— | — | @@ -0,0 +1,10 @@ |
| 2 | + |
| 3 | + <li><a href="query.cgi?format=specific">Search bugs</a></li> |
| 4 | + <li><a href="query.cgi?format=advanced">Advanced search</a></li> |
| 5 | + <li><a href="enter_bug.cgi">Enter a new [% terms.bug %]</a></li> |
| 6 | + [% IF doc_section && Param('docs_urlbase') %] |
| 7 | + <li> |
| 8 | + <a href="[% docs_urlbase _ doc_section FILTER html %]" target="_blank">Help</a> |
| 9 | + </li> |
| 10 | + [% END %] |
| 11 | + |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/global/search-links.html.tmpl |
— | — | @@ -0,0 +1,31 @@ |
| 2 | + |
| 3 | +[%# Saved searches %] |
| 4 | + |
| 5 | + [% IF user.showmybugslink %] |
| 6 | + [% filtered_username = user.login FILTER url_quote %] |
| 7 | + <li><a href="[% Param('mybugstemplate').replace('%userid%', filtered_username) %]">My [% terms.Bugs %]</a></li> |
| 8 | + [% END %] |
| 9 | + |
| 10 | + [% FOREACH q = user.queries %] |
| 11 | + [% IF q.link_in_footer %] |
| 12 | + <li> |
| 13 | + <a href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]">[% q.name FILTER html %]</a> |
| 14 | + </li> |
| 15 | + [% END %] |
| 16 | + [% END %] |
| 17 | + [% FOREACH q = user.queries_subscribed %] |
| 18 | + [% IF new_line %] |
| 19 | + <br> |
| 20 | + [% new_line = 0 %] |
| 21 | + [% END %] |
| 22 | + <li> |
| 23 | + <a href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd= |
| 24 | + [% q.name FILTER url_quote %]&sharer_id= |
| 25 | + [% q.user.id FILTER url_quote %]" |
| 26 | + class="shared" |
| 27 | + title="Shared by [% q.user.identity FILTER html %]" |
| 28 | + >[% q.name FILTER html FILTER no_break %] |
| 29 | + </a> |
| 30 | + </li> |
| 31 | + [% END %] |
| 32 | + |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/global/header.html.tmpl |
— | — | @@ -0,0 +1,145 @@ |
| 2 | +[% IF message %] |
| 3 | + [% PROCESS global/messages.html.tmpl %] |
| 4 | +[% END %] |
| 5 | + |
| 6 | +[% DEFAULT |
| 7 | + subheader = "" |
| 8 | + header_addl_info = "" |
| 9 | + onload = "" |
| 10 | + style_urls = [] |
| 11 | +%] |
| 12 | + |
| 13 | + |
| 14 | +<html> |
| 15 | + <head> |
| 16 | + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
| 17 | + <meta name="generator" content="Buzilla" /> |
| 18 | + <link rel="stylesheet" href="skins/custom/vector.css" media="screen" /> |
| 19 | + |
| 20 | + <meta name="robots" content="index,follow"> |
| 21 | + <title>[% title %]</title> |
| 22 | + |
| 23 | +[%# Migration note: contents of the old Param 'headerhtml' would go here %] |
| 24 | + |
| 25 | + [% PROCESS "global/site-navigation.html.tmpl" %] |
| 26 | + |
| 27 | + [% PROCESS 'global/setting-descs.none.tmpl' %] |
| 28 | + |
| 29 | + [%# Set up the skin CSS cascade: |
| 30 | + # 1. Standard Bugzilla stylesheet set (persistent) |
| 31 | + # 2. Standard Bugzilla stylesheet set (selectable) |
| 32 | + # 3. All third-party "skin" stylesheet sets (selectable) |
| 33 | + # 4. Page-specific styles |
| 34 | + # 5. Custom Bugzilla stylesheet set (persistent) |
| 35 | + # "Selectable" skin file sets may be either preferred or alternate. |
| 36 | + # Exactly one is preferred, determined by the "skin" user preference. |
| 37 | + #%] |
| 38 | + [% IF user.settings.skin.value != 'standard' %] |
| 39 | + [% user_skin = user.settings.skin.value %] |
| 40 | + [% END %] |
| 41 | + [% style_urls.unshift('skins/standard/global.css') %] |
| 42 | + |
| 43 | + |
| 44 | + [%# CSS cascade, part 4: page-specific styles. |
| 45 | + #%] |
| 46 | + [% IF style %] |
| 47 | + <style type="text/css"> |
| 48 | + [% style %] |
| 49 | + </style> |
| 50 | + [% END %] |
| 51 | + |
| 52 | + [%# CSS cascade, part 5: Custom Bugzilla stylesheet set (persistent). |
| 53 | + # Always present. Site administrators may override all other style |
| 54 | + # definitions, including skins, using custom stylesheets. |
| 55 | + #%] |
| 56 | + [% FOREACH style_url = style_urls %] |
| 57 | + [% IF style_url.match('^skins/standard/') %] |
| 58 | + <link href="[% style_url.replace('^skins/standard/', "skins/custom/") |
| 59 | + FILTER html %]" rel="stylesheet" type="text/css"> |
| 60 | + [% END %] |
| 61 | + [% END %] |
| 62 | + <!--[if lte IE 7]> |
| 63 | + [%# Internet Explorer treats [if IE] HTML comments as uncommented. |
| 64 | + # Use it to import CSS fixes so that Bugzilla looks decent on IE 7 |
| 65 | + # and below. |
| 66 | + #%] |
| 67 | + <link href="skins/custom/IE-fixes.css" |
| 68 | + rel="stylesheet" |
| 69 | + type="text/css"> |
| 70 | + <![endif]--> |
| 71 | + |
| 72 | + <script src="js/yui/yahoo-dom-event.js" type="text/javascript"></script> |
| 73 | + <script src="js/global.js" type="text/javascript"></script> |
| 74 | + <script type="text/javascript"> |
| 75 | + <!-- |
| 76 | + YAHOO.namespace('bugzilla'); |
| 77 | + if (YAHOO.env.ua.gecko) { |
| 78 | + YAHOO.util.Event._simpleRemove(window, "unload", |
| 79 | + YAHOO.util.Event._unload); |
| 80 | + } |
| 81 | + [%# Make some Bugzilla information available to all scripts. |
| 82 | + # We don't import every parameter and constant because we |
| 83 | + # don't want to add a lot of uncached JS to every page. |
| 84 | + #%] |
| 85 | + var BUGZILLA = { |
| 86 | + param: { |
| 87 | + cookiepath: '[% Param('cookiepath') FILTER js %]' |
| 88 | + } |
| 89 | + }; |
| 90 | + [% IF javascript %] |
| 91 | + [% javascript %] |
| 92 | + [% END %] |
| 93 | + // --> |
| 94 | + </script> |
| 95 | + |
| 96 | + [% IF javascript_urls %] |
| 97 | + [% FOREACH javascript_url = javascript_urls %] |
| 98 | + <script src="[% javascript_url FILTER html %]" type="text/javascript"></script> |
| 99 | + [% END %] |
| 100 | + [% END %] |
| 101 | + |
| 102 | + [%# this puts the live bookmark up on firefox for the Atom feed %] |
| 103 | + [% IF atomlink %] |
| 104 | + <link rel="alternate" |
| 105 | + type="application/atom+xml" title="Atom feed" |
| 106 | + href="[% atomlink FILTER html %]"> |
| 107 | + [% END %] |
| 108 | + |
| 109 | + [%# Required for the 'Autodiscovery' feature in Firefox 2 and IE 7. %] |
| 110 | + <link rel="search" type="application/opensearchdescription+xml" |
| 111 | + title="[% terms.Bugzilla %]" href="./search_plugin.cgi"> |
| 112 | + <link rel="shortcut icon" href="images/favicon.ico" > |
| 113 | + [% Hook.process("additional_header") %] |
| 114 | + |
| 115 | + </head> |
| 116 | + |
| 117 | +[%# Migration note: contents of the old Param 'bodyhtml' go in the body tag, |
| 118 | + # but set the onload attribute in the DEFAULT directive above. |
| 119 | + #%] |
| 120 | + |
| 121 | + <body class="skin-vector" dir="ltr" onload="[% onload %]" |
| 122 | + class="[% urlbase.replace('^https?://','').replace('/$','').replace('[-~@:/.]+','-') %] |
| 123 | + [% FOREACH class = bodyclasses %] |
| 124 | + [% ' ' %][% class FILTER css_class_quote %] |
| 125 | + [% END %]"> |
| 126 | + |
| 127 | + <div id="page-base" class="noprint"></div> |
| 128 | + <div id="head-base" class="noprint"></div> |
| 129 | + <!-- content --> |
| 130 | + <div id="content-container" > |
| 131 | + <a id="top"></a> |
| 132 | + <!-- bodyContent --> |
| 133 | + <div id="bodyContent"> |
| 134 | + |
| 135 | +[% IF header_addl_info %] |
| 136 | + <p class="header_addl_info">[% header_addl_info %]</p> |
| 137 | + [% END %] |
| 138 | + |
| 139 | + |
| 140 | +[% IF Param('announcehtml') %] |
| 141 | +[% Param('announcehtml') FILTER none %] |
| 142 | +[% END %] |
| 143 | + |
| 144 | +[% IF message %] |
| 145 | +<div id="message">[% message %]</div> |
| 146 | +[% END %] |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/global/user-links.html.tmpl |
— | — | @@ -0,0 +1,31 @@ |
| 2 | + <li><a href="report.cgi">Reports</a></li> |
| 3 | + [% IF Param('shutdownhtml') || Bugzilla.has_flags %] |
| 4 | + <li> |
| 5 | + [% IF user.id %] |
| 6 | + <a href="request.cgi?requester=[% user.login FILTER url_quote %]&requestee= |
| 7 | + [% user.login FILTER url_quote %]&do_union=1&group=type&action=queue">My Requests</a> |
| 8 | + [% ELSE %] |
| 9 | + <a href="request.cgi">Requests</a> |
| 10 | + [% END %] |
| 11 | + </li> |
| 12 | + [% END %] |
| 13 | + [% IF user.id && Param('usevotes') %] |
| 14 | + <li><a href="votes.cgi?action=show_user">My Votes</a></li> |
| 15 | + [% END %] |
| 16 | + |
| 17 | + [% IF user.login %] |
| 18 | + <li><a href="userprefs.cgi">Preferences</a></li> |
| 19 | + [% IF user.in_group('tweakparams') || user.in_group('editusers') || user.can_bless |
| 20 | + || (Param('useclassification') && user.in_group('editclassifications')) |
| 21 | + || user.in_group('editcomponents') || user.in_group('admin') || user.in_group('creategroups') |
| 22 | + || user.in_group('editkeywords') || user.in_group('bz_canusewhines') |
| 23 | + || user.get_products_by_permission("editcomponents").size %] |
| 24 | + <li><a href="admin.cgi">Administration</a></li> |
| 25 | + [% END %] |
| 26 | + [% END %] |
| 27 | + |
| 28 | + [% PROCESS "global/per-bug-queries.html.tmpl" %] |
| 29 | + |
| 30 | + [%# Sections of links to more things users can do on this installation. %] |
| 31 | + [% Hook.process("end") %] |
| 32 | + |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/global/footer.html.tmpl |
— | — | @@ -0,0 +1,126 @@ |
| 2 | +[% PROCESS global/variables.none.tmpl %] |
| 3 | + <div class="visualClear"></div> |
| 4 | + </div> |
| 5 | + <!-- /bodyContent --> |
| 6 | + </div> |
| 7 | + <!-- /content --> |
| 8 | + <!-- header --> |
| 9 | + <div id="head" class="noprint"> |
| 10 | + <!-- /search --> |
| 11 | + <div id="p-search"> |
| 12 | + <h5><label for="searchInput">Search</label></h5> |
| 13 | + <form id="searchform" action="buglist.cgi" method="get" |
| 14 | + onsubmit="if (this.quicksearch.value == '') |
| 15 | + { alert('Please enter one or more search terms first.'); |
| 16 | + return false; } return true;"> |
| 17 | + <input type='hidden' name="title" value="Special:Search"/> |
| 18 | + <div id="simpleSearch"> |
| 19 | + <input id="searchInput" name="quicksearch" type="text" title="Search Bugzilla" value="" /> |
| 20 | + <button id="searchButton" type='submit' name='button' title="Search Bugzilla for this text"> </button> |
| 21 | + </div> |
| 22 | + </form> |
| 23 | + </div> |
| 24 | + <!-- /search --> |
| 25 | + <!-- personal --> |
| 26 | + <div id="p-personal" class=""> |
| 27 | + <h5>Personal tools</h5> |
| 28 | + <ul > |
| 29 | + [% IF user.login %] |
| 30 | + [% IF user.authorizer.can_logout %] |
| 31 | + <li class="user-link"> |
| 32 | + [% IF sudoer %] |
| 33 | + [%+ sudoer.login FILTER html %] (<b>impersonating |
| 34 | + [%+ user.login FILTER html %]</b> |
| 35 | + <a href="relogin.cgi?action=end-sudo">end session</a>) |
| 36 | + [% ELSE %] |
| 37 | + <a href="userprefs.cgi" title="Preferences">[%+ user.login FILTER html %]</a> |
| 38 | + [% END %] |
| 39 | + </li> |
| 40 | + <li><a href="index.cgi?logout=1" title="Log out">Log out</a></li> |
| 41 | + [% ELSE %] |
| 42 | + <li>Logged in as$nbsp;[%+ user.login FILTER html %]</li> |
| 43 | + [% END %] |
| 44 | + [% ELSE %] |
| 45 | + [% IF Param('createemailregexp') |
| 46 | + && user.authorizer.user_can_create_account %] |
| 47 | + <li id="new_account_container[% qs_suffix FILTER html %]"> |
| 48 | + <a href="createaccount.cgi">New Account</a> |
| 49 | + </li> |
| 50 | + [% END %] |
| 51 | + [%# Only display one login form when we're on a LOGIN_REQUIRED page. That |
| 52 | + # way, we're guaranteed that the user will use the form that has |
| 53 | + # hidden_fields in it (the center form) instead of this one. Also, it's |
| 54 | + # less confusing to have one form (as opposed to three) when you're |
| 55 | + # required to log in. |
| 56 | + #%] |
| 57 | + [% IF user.authorizer.can_login && !Bugzilla.page_requires_login %] |
| 58 | + [% PROCESS "account/auth/login-small.html.tmpl" %] |
| 59 | + [% END %] |
| 60 | + |
| 61 | + [% END %] |
| 62 | + </ul> |
| 63 | + </div> |
| 64 | + <!-- /personal --> |
| 65 | + </div> |
| 66 | + <!-- /header --> |
| 67 | + <!-- panel --> |
| 68 | + <div id="panel" class="noprint"> |
| 69 | + <!-- logo --> |
| 70 | + <div id="p-logo"><a style="background-image: url(skins/custom/images/bugzilla-logo.png);" href="./" title="Visit the main page"></a></div> |
| 71 | + <!-- /logo --> |
| 72 | + <!-- navigation --> |
| 73 | + <div class="portal"> |
| 74 | + <h5>Navigation</h5> |
| 75 | + <div class="body"> |
| 76 | + <ul> |
| 77 | + [% PROCESS "global/nav-links.html.tmpl" %] |
| 78 | + </ul> |
| 79 | + </div> |
| 80 | + </div> |
| 81 | + <!-- /navigation --> |
| 82 | + <!-- interaction --> |
| 83 | + [% IF user.showmybugslink OR user.queries.size |
| 84 | + OR user.queries_subscribed.size |
| 85 | + %] |
| 86 | + <div class="portal"> |
| 87 | + <h5>Saved Searches</h5> |
| 88 | + <div class="body"> |
| 89 | + <ul> |
| 90 | + [% PROCESS "global/search-links.html.tmpl" %] |
| 91 | + </ul> |
| 92 | + </div> |
| 93 | + </div> |
| 94 | + [% END %] |
| 95 | + <!-- /interaction --> |
| 96 | + <!-- toolbox --> |
| 97 | + <div class="portal"> |
| 98 | + <h5>Links</h5> |
| 99 | + <div class="body"> |
| 100 | + <ul> |
| 101 | + [% PROCESS "global/user-links.html.tmpl" %] |
| 102 | + </ul> |
| 103 | + </div> |
| 104 | + </div> |
| 105 | + <!-- /toolbox --> |
| 106 | + </div> |
| 107 | + <!-- /panel --> |
| 108 | + |
| 109 | + <!-- footer --> |
| 110 | + <div id="footer" > |
| 111 | + <ul id="footer-info"> |
| 112 | + <li>Bugzilla version [%+ constants.BUGZILLA_VERSION %]</li> |
| 113 | + </ul> |
| 114 | + |
| 115 | + <ul id="footer-places"> |
| 116 | + <li><a href="http://wikimediafoundation.org/wiki/Privacy_policy" title="wikimedia:Privacy policy">Privacy policy</a></li> |
| 117 | + <li><a href="http://www.mediawiki.org/wiki/Project:About" title="Project:About">About MediaWiki.org</a></li> |
| 118 | + <li><a href="http://www.mediawiki.org/wiki/Project:General_disclaimer" title="Project:General disclaimer">Disclaimers</a></li> |
| 119 | + </ul> |
| 120 | + <ul id="footer-icons" class="noprint"> |
| 121 | + <li id="footer-icon-poweredby"><a href="http://www.bugzilla.org/"><img src="skins/custom/images/bugzilla-badge.png" height="31" width="88" alt="Powered by Bugzilla" /></a></li> |
| 122 | + </ul> |
| 123 | + <div style="clear:both"></div> |
| 124 | + </div> |
| 125 | + <!-- /footer --> |
| 126 | + </body> |
| 127 | +</html> |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/index.html.tmpl |
— | — | @@ -0,0 +1,101 @@ |
| 2 | +[%# 1.0@bugzilla.org %] |
| 3 | +[%# -*- mode: html -*- %] |
| 4 | +[%# The contents of this file are subject to the Mozilla Public |
| 5 | + # License Version 1.1 (the "License"); you may not use this file |
| 6 | + # except in compliance with the License. You may obtain a copy of |
| 7 | + # the License at http://www.mozilla.org/MPL/ |
| 8 | + # |
| 9 | + # Software distributed under the License is distributed on an "AS |
| 10 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 | + # implied. See the License for the specific language governing |
| 12 | + # rights and limitations under the License. |
| 13 | + # |
| 14 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 15 | + # |
| 16 | + # The Initial Developer of the Original Code is Netscape Communications |
| 17 | + # Corporation. Portions created by Netscape are |
| 18 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 19 | + # Rights Reserved. |
| 20 | + # |
| 21 | + # Contributor(s): Terry Weissman <terry@mozilla.org> |
| 22 | + # Jacob Steenhagen <jake@bugzilla.org> |
| 23 | + # Vitaly Harisov <vitaly@rathedg.com> |
| 24 | + #%] |
| 25 | + |
| 26 | +[%# INTERFACE: |
| 27 | + # release: a hash containing data about new releases, if any. |
| 28 | + #%] |
| 29 | + |
| 30 | +[% PROCESS global/variables.none.tmpl %] |
| 31 | + |
| 32 | + |
| 33 | +[% PROCESS global/header.html.tmpl |
| 34 | + title = "$terms.Bugzilla Main Page" |
| 35 | + header = "Main Page" |
| 36 | +%] |
| 37 | + |
| 38 | +<link rel="stylesheet" href="skins/custom/index.css" media="screen" /> |
| 39 | + |
| 40 | +<div id="page-index"> |
| 41 | + <div class="intro"> |
| 42 | + <img src="skins/custom/bugzilla-ayb.png" width="308" height="236" border="2" alt="bugzzz"/> |
| 43 | + </div> |
| 44 | + |
| 45 | + <p>This is the new bug tracker for <a |
| 46 | +href="http://www.mediawiki.org/">MediaWiki</a> and its extensions |
| 47 | +and site-specific problems on <a |
| 48 | +href="http://www.wikimedia.org/">Wikimedia's</a> wiki sites.</p> |
| 49 | + |
| 50 | + <p>Welcome to [% terms.Bugzilla %]. To see what's new in this version |
| 51 | + of [% terms.Bugzilla %], see the |
| 52 | + <a href="page.cgi?id=release-notes.html">release notes</a>! |
| 53 | + You may also want to read the |
| 54 | + <a href="[% Param('docs_urlbase') FILTER html %]using.html"> |
| 55 | + [%- terms.Bugzilla %] User's Guide</a> to find out more about |
| 56 | + [%+ terms.Bugzilla %] and how to use it.</p> |
| 57 | + |
| 58 | + |
| 59 | + <p>For help using this system, please see |
| 60 | + <a |
| 61 | +href="http://www.mediawiki.org/wiki/Bugzilla">Mediawiki:Bugzilla</a>.</p> |
| 62 | + |
| 63 | + <p><b>Not sure how to explain your problem clearly? Read |
| 64 | + <a href="http://www.chiark.greenend.org.uk/~sgtatham/bugs.html"><i>How |
| 65 | +to Report Bugs Effectively</i></a> for some general pointers.</b></p> |
| 66 | + |
| 67 | + <div style="clear:both;"></div> |
| 68 | + <hr /> |
| 69 | + |
| 70 | + <p>But it all boils down to a choice of:</p> |
| 71 | + <ul> |
| 72 | + <li><a href="query.cgi">Search existing [% terms.bug %] reports</a></li> |
| 73 | + <li><a href="enter_bug.cgi">Enter a new [% terms.bug %] report</a></li> |
| 74 | + <li id="report"><a href="report.cgi">Summary reports and charts</a></li> |
| 75 | + <li><a href="javascript:addSidebar()">Add to Sidebar</a> (requires a Mozilla browser like Mozilla Firefox)</li> |
| 76 | + <li id="quick_search_plugin"> |
| 77 | + <a href="javascript:window.external.AddSearchProvider('[% Param('urlbase') %]search_plugin.cgi')">Install |
| 78 | + the Quick Search plugin</a> (requires Firefox 2 or Internet Explorer 7) |
| 79 | + </li> |
| 80 | + |
| 81 | + |
| 82 | + [%# List items of links to more things users can do on this installation. %] |
| 83 | + [% Hook.process("links") %] |
| 84 | + |
| 85 | + </ul> |
| 86 | + |
| 87 | + <form id="f" name="f" action="buglist.cgi" method="get" |
| 88 | + onsubmit="if (this.quicksearch.value == '') |
| 89 | + { alert('Please enter one or more search terms first.'); |
| 90 | + return false; } return true;"> |
| 91 | + <div> |
| 92 | + <p>Enter [% terms.abug %] # or some search terms:</p> |
| 93 | + <input id="quicksearch" type="text" name="quicksearch"> |
| 94 | + <input id="find" type="submit" value="Find"> |
| 95 | + <a href="page.cgi?id=quicksearch.html">[Help]</a> |
| 96 | + </div> |
| 97 | + </form> |
| 98 | + |
| 99 | + <div class="outro"></div> |
| 100 | +</div> |
| 101 | + |
| 102 | +[% PROCESS global/footer.html.tmpl %] |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/config.json.tmpl |
— | — | @@ -0,0 +1,299 @@ |
| 2 | +[%# The contents of this file are subject to the Mozilla Public |
| 3 | + # License Version 1.1 (the "License"); you may not use this file |
| 4 | + # except in compliance with the License. You may obtain a copy of |
| 5 | + # the License at http://www.mozilla.org/MPL/ |
| 6 | + # |
| 7 | + # Software distributed under the License is distributed on an "AS |
| 8 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + # implied. See the License for the specific language governing |
| 10 | + # rights and limitations under the License. |
| 11 | + # |
| 12 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + # |
| 14 | + # The Initial Developer of the Original Code is Netscape Communications |
| 15 | + # Corporation. Portions created by Netscape are |
| 16 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + # Rights Reserved. |
| 18 | + # |
| 19 | + # Contributor(s): Gervase Markham <gerv@gerv.net> |
| 20 | + #%] |
| 21 | + |
| 22 | +[% |
| 23 | + # Pinched from Bugzilla/API/Model/Utils.pm in BzAPI - need to keep in sync |
| 24 | + OLD2NEW = { |
| 25 | + 'opendate' => 'creation_time', # query |
| 26 | + 'creation_ts' => 'creation_time', |
| 27 | + 'changeddate' => 'last_change_time', # query |
| 28 | + 'delta_ts' => 'last_change_time', |
| 29 | + 'bug_id' => 'id', |
| 30 | + 'rep_platform' => 'platform', |
| 31 | + 'bug_severity' => 'severity', |
| 32 | + 'bug_status' => 'status', |
| 33 | + 'short_desc' => 'summary', |
| 34 | + 'short_short_desc' => 'summary', |
| 35 | + 'bug_file_loc' => 'url', |
| 36 | + 'status_whiteboard' => 'whiteboard', |
| 37 | + 'cclist_accessible' => 'is_cc_accessible', |
| 38 | + 'reporter_accessible' => 'is_reporter_accessible', |
| 39 | + 'everconfirmed' => 'is_everconfirmed', |
| 40 | + 'dependson' => 'depends_on', |
| 41 | + 'blocked' => 'blocks', |
| 42 | + 'attachment' => 'attachments', |
| 43 | + 'flag' => 'flags', |
| 44 | + 'flagtypes.name' => 'flag', |
| 45 | + 'bug_group' => 'group', |
| 46 | + 'group' => 'groups', |
| 47 | + 'longdesc' => 'comment', |
| 48 | + 'bug_file_loc_type' => 'url_type', |
| 49 | + 'bugidtype' => 'id_mode', |
| 50 | + 'longdesc_type' => 'comment_type', |
| 51 | + 'short_desc_type' => 'summary_type', |
| 52 | + 'status_whiteboard_type' => 'whiteboard_type', |
| 53 | + 'emailassigned_to1' => 'email1_assigned_to', |
| 54 | + 'emailassigned_to2' => 'email2_assigned_to', |
| 55 | + 'emailcc1' => 'email1_cc', |
| 56 | + 'emailcc2' => 'email2_cc', |
| 57 | + 'emailqa_contact1' => 'email1_qa_contact', |
| 58 | + 'emailqa_contact2' => 'email2_qa_contact', |
| 59 | + 'emailreporter1' => 'email1_reporter', |
| 60 | + 'emailreporter2' => 'email2_reporter', |
| 61 | + 'emaillongdesc1' => 'email1_comment_author', |
| 62 | + 'emaillongdesc2' => 'email2_comment_author', |
| 63 | + 'emailtype1' => 'email1_type', |
| 64 | + 'emailtype2' => 'email2_type', |
| 65 | + 'chfieldfrom' => 'changed_after', |
| 66 | + 'chfieldto' => 'changed_before', |
| 67 | + 'chfield' => 'changed_field', |
| 68 | + 'chfieldvalue' => 'changed_field_to', |
| 69 | + 'deadlinefrom' => 'deadline_after', |
| 70 | + 'deadlineto' => 'deadline_before', |
| 71 | + 'attach_data.thedata' => 'attachment.data', |
| 72 | + 'longdescs.isprivate' => 'comment.is_private', |
| 73 | + 'commenter' => 'comment.author', |
| 74 | + 'flagtypes.name' => 'flag', |
| 75 | + 'requestees.login_name' => 'flag.requestee', |
| 76 | + 'setters.login_name' => 'flag.setter', |
| 77 | + 'days_elapsed' => 'idle', |
| 78 | + 'owner_idle_time' => 'assignee_idle', |
| 79 | + 'dup_id' => 'dupe_of', |
| 80 | + 'isopened' => 'is_open', |
| 81 | + 'flag_type' => 'flag_types', |
| 82 | + }; |
| 83 | + |
| 84 | + OLDATTACH2NEW = { |
| 85 | + 'submitter' => 'attacher', |
| 86 | + 'description' => 'description', |
| 87 | + 'filename' => 'file_name', |
| 88 | + 'delta_ts' => 'last_change_time', |
| 89 | + 'isurl' => 'is_url', |
| 90 | + 'isobsolete' => 'is_obsolete', |
| 91 | + 'ispatch' => 'is_patch', |
| 92 | + 'isprivate' => 'is_private', |
| 93 | + 'mimetype' => 'content_type', |
| 94 | + 'contenttypeentry' => 'content_type', |
| 95 | + 'date' => 'creation_time', |
| 96 | + 'attachid' => 'id', |
| 97 | + 'desc' => 'description', |
| 98 | + 'flag' => 'flags', |
| 99 | + 'type' => 'content_type' |
| 100 | + }; |
| 101 | +%] |
| 102 | + |
| 103 | +[%# Add attachment stuff to the main hash - but with right prefix. (This is |
| 104 | + # the way the code is structured in BzAPI, and changing it makes it harder |
| 105 | + # to keep the two in sync.) |
| 106 | + #%] |
| 107 | +[% FOREACH entry IN OLDATTACH2NEW %] |
| 108 | + [% newkey = 'attachments.' _ entry.key %] |
| 109 | + [% OLD2NEW.${newkey} = 'attachment.' _ OLDATTACH2NEW.${entry.key} %] |
| 110 | +[% END %] |
| 111 | + |
| 112 | +[% all_visible_flag_types = {} %] |
| 113 | + |
| 114 | +{ |
| 115 | + "version": "[% constants.BUGZILLA_VERSION FILTER json %]", |
| 116 | + "maintainer": "[% Param('maintainer') FILTER json %]", |
| 117 | + "announcement": "[% Param('announcehtml') FILTER json %]", |
| 118 | + "max_attachment_size": "[% (Param('maxattachmentsize') * 1000) FILTER json %]", |
| 119 | + |
| 120 | +[% IF Param('useclassification') %] |
| 121 | + [% classifications = user.get_selectable_classifications() %] |
| 122 | + [% cl_name_for = {} %] |
| 123 | + "classification": { |
| 124 | + [% FOREACH cl IN classifications %] |
| 125 | + [% cl_name_for.${cl.id} = cl.name %] |
| 126 | + "[% cl.name FILTER json %]": { |
| 127 | + "id": [% cl.id %], |
| 128 | + "products": [ |
| 129 | + [% FOREACH product IN cl.products %] |
| 130 | + "[% product.name FILTER json %]"[% ',' UNLESS loop.last() %] |
| 131 | + [% END %] |
| 132 | + ] |
| 133 | + }[% ',' UNLESS loop.last() %] |
| 134 | + [% END %] |
| 135 | + }, |
| 136 | +[% END %] |
| 137 | + |
| 138 | + "product": { |
| 139 | + [% FOREACH product = products %] |
| 140 | + "[% product.name FILTER json %]": { |
| 141 | + "id": [% product.id %], |
| 142 | +[% IF Param('useclassification') %] |
| 143 | + "classification": "[% cl_name_for.${product.classification_id} FILTER json %]", |
| 144 | +[% END %] |
| 145 | + "component": { |
| 146 | + [% FOREACH component = product.components %] |
| 147 | + "[% component.name FILTER json %]": { |
| 148 | + "id": [% component.id %], |
| 149 | + "flag_type": [ |
| 150 | + [% flag_types = |
| 151 | + component.flag_types.bug.merge(component.flag_types.attachment) %] |
| 152 | + [%-# "first" flag used to get commas right; can't use loop.last() in case |
| 153 | + # last flag is inactive %] |
| 154 | + [% first = 1 %] |
| 155 | + [% FOREACH flag_type = flag_types %] |
| 156 | + [% NEXT UNLESS flag_type.is_active %] |
| 157 | + [% all_visible_flag_types.${flag_type.id} = flag_type %] |
| 158 | + [% ',' UNLESS first %][% flag_type.id FILTER json %][% first = 0 %] |
| 159 | + [% END %]] |
| 160 | + } [% ',' UNLESS loop.last() %] |
| 161 | + [% END %] |
| 162 | + }, |
| 163 | + "version": [ |
| 164 | + [% FOREACH version = product.versions %] |
| 165 | + "[% version.name FILTER json %]"[% ',' UNLESS loop.last() %] |
| 166 | + [% END %] |
| 167 | + ], |
| 168 | + |
| 169 | +[% IF Param('usetargetmilestone') %] |
| 170 | + "target_milestone": [ |
| 171 | + [% FOREACH milestone = product.milestones %] |
| 172 | + "[% milestone.name FILTER json %]"[% ',' UNLESS loop.last() %] |
| 173 | + [% END %] |
| 174 | + ], |
| 175 | +[% END %] |
| 176 | + |
| 177 | + "group": [ |
| 178 | + [% FOREACH group = product.groups_valid %] |
| 179 | + [% group.id %][% ',' UNLESS loop.last() %] |
| 180 | + [% END %] |
| 181 | + ] |
| 182 | + }[% ',' UNLESS loop.last() %] |
| 183 | + [% END %] |
| 184 | + }, |
| 185 | + |
| 186 | + "group": { |
| 187 | + [% FOREACH group = product.groups_valid %] |
| 188 | + "[% group.id %]": { |
| 189 | + "name": "[% group.name FILTER json %]", |
| 190 | + "description": "[% group.description FILTER json %]", |
| 191 | + "is_accepting_bugs": [% group.is_bug_group %], |
| 192 | + "is_active": [% group.is_active %] |
| 193 | + }[% ',' UNLESS loop.last() %] |
| 194 | + [% END %] |
| 195 | + }, |
| 196 | + |
| 197 | + "flag_type": { |
| 198 | + [% FOREACH flag_type = all_visible_flag_types.values.sort('name') %] |
| 199 | + "[%+ flag_type.id %]": { |
| 200 | + "name": "[% flag_type.name FILTER json %]", |
| 201 | + "description": "[% flag_type.description FILTER json %]", |
| 202 | + [% IF user.in_group("editcomponents") %] |
| 203 | + "request_group": [% flag_type.request_group.id %], |
| 204 | + "grant_group": [% flag_type.grant_group.id %], |
| 205 | + [% END %] |
| 206 | + "is_for_bugs": [% flag_type.target_type == "bug" ? 1 : 0 %], |
| 207 | + "is_requestable": [% flag_type.is_requestable %], |
| 208 | + "is_specifically_requestable": [% flag_type.is_requesteeble %], |
| 209 | + "is_multiplicable": [% flag_type.is_multiplicable %] |
| 210 | + }[% ',' UNLESS loop.last() %] |
| 211 | + [% END %] |
| 212 | + }, |
| 213 | + |
| 214 | + [% PROCESS "global/field-descs.none.tmpl" %] |
| 215 | + |
| 216 | + [%# Put custom field value data where below loop expects to find it %] |
| 217 | + [% FOREACH cf = custom_fields %] |
| 218 | + [% ${cf.name} = [] %] |
| 219 | + [% FOREACH value = cf.legal_values %] |
| 220 | + [% ${cf.name}.push(value.name) %] |
| 221 | + [% END %] |
| 222 | + [% END %] |
| 223 | + |
| 224 | + [%# Built-in fields do not have type IDs. There aren't ID values for all |
| 225 | + # the types of the built-in fields, but we do what we can, and leave the |
| 226 | + # rest as "0" (unknown). |
| 227 | + #%] |
| 228 | + [% type_id_for = { |
| 229 | + "id" => 6, |
| 230 | + "summary" => 1, |
| 231 | + "classification" => 2, |
| 232 | + "version" => 2, |
| 233 | + "url" => 1, |
| 234 | + "whiteboard" => 1, |
| 235 | + "keywords" => 3, |
| 236 | + "component" => 2, |
| 237 | + "attachment.description" => 1, |
| 238 | + "attachment.file_name" => 1, |
| 239 | + "attachment.content_type" => 1, |
| 240 | + "target_milestone" => 2, |
| 241 | + "comment" => 4, |
| 242 | + "alias" => 1, |
| 243 | + "deadline" => 5, |
| 244 | + } %] |
| 245 | + |
| 246 | + "field": { |
| 247 | + [% FOREACH item = field %] |
| 248 | + [% newname = OLD2NEW.${item.name} || item.name %] |
| 249 | + "[% newname FILTER json %]": { |
| 250 | + "description": "[% (field_descs.${item.name} OR |
| 251 | + item.description) FILTER json %]", |
| 252 | + [% blacklist = ["version", "group", "product", "component"] %] |
| 253 | + [% IF ${newname} AND NOT blacklist.contains(newname) %] |
| 254 | + "values": [ |
| 255 | + [% FOREACH value = ${newname} %] |
| 256 | + "[% value FILTER json %]"[% ',' UNLESS loop.last() %] |
| 257 | + [% END %] |
| 258 | + ], |
| 259 | + [% END %] |
| 260 | + [% paramname = newname.replace("_", "") %] [%# For op_sys... %] |
| 261 | + [% IF Param('default' _ paramname) %] |
| 262 | + "default": "[% Param('default' _ paramname) %]", |
| 263 | + [% END %] |
| 264 | + [%-# The 'status' hash has a lot of extra stuff %] |
| 265 | + [% IF newname == "status" %] |
| 266 | + "open": [ |
| 267 | + [% FOREACH value = open_status %] |
| 268 | + "[% value FILTER json %]"[% ',' UNLESS loop.last() %] |
| 269 | + [% END %] |
| 270 | + ], |
| 271 | + "closed": [ |
| 272 | + [% FOREACH value = closed_status %] |
| 273 | + "[% value FILTER json %]"[% ',' UNLESS loop.last() %] |
| 274 | + [% END %] |
| 275 | + ], |
| 276 | + "transitions": { |
| 277 | + "{Start}": [ |
| 278 | + [% FOREACH target = initial_status %] |
| 279 | + "[% target.name %]"[% ',' UNLESS loop.last() %] |
| 280 | + [% END %] |
| 281 | + ], |
| 282 | + [% FOREACH status = status_objects %] |
| 283 | + [% targets = status.can_change_to() %] |
| 284 | + "[% status.name FILTER json %]": [ |
| 285 | + [% FOREACH target = targets %] |
| 286 | + "[% target.name %]"[% ',' UNLESS loop.last() %] |
| 287 | + [% END %] |
| 288 | + ][% ',' UNLESS loop.last() %] |
| 289 | + [% END %] |
| 290 | + }, |
| 291 | + [% END %] |
| 292 | + [% IF newname.match("^cf_") %] |
| 293 | + "is_on_bug_entry": [% item.enter_bug %], |
| 294 | + [% END %] |
| 295 | + "type": [% item.type || type_id_for.$newname || 0 %] |
| 296 | + }[% ',' UNLESS loop.last() %] |
| 297 | + [% END %] |
| 298 | + } |
| 299 | +} |
| 300 | + |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/account/auth/login-small.html.tmpl |
— | — | @@ -0,0 +1,119 @@ |
| 2 | +[%# The contents of this file are subject to the Mozilla Public |
| 3 | + # License Version 1.1 (the "License"); you may not use this file |
| 4 | + # except in compliance with the License. You may obtain a copy of |
| 5 | + # the License at http://www.mozilla.org/MPL/ |
| 6 | + # |
| 7 | + # Software distributed under the License is distributed on an "AS |
| 8 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + # implied. See the License for the specific language governing |
| 10 | + # rights and limitations under the License. |
| 11 | + # |
| 12 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + # |
| 14 | + # The Initial Developer of the Original Code is Netscape Communications |
| 15 | + # Corporation. Portions created by Netscape are |
| 16 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + # Rights Reserved. |
| 18 | + # |
| 19 | + # Contributor(s): Jacob Steenhagen <jake@bugzilla.org> |
| 20 | + #%] |
| 21 | + |
| 22 | +[% PROCESS global/variables.none.tmpl %] |
| 23 | + |
| 24 | +[%# Use the current script name. If an empty name is returned, |
| 25 | + # then we are accessing the home page. %] |
| 26 | + |
| 27 | +[% login_target = cgi.url("-relative" => 1, "-query" => 1) %] |
| 28 | +[% IF !login_target || login_target.match('^token.cgi') %] |
| 29 | + [% login_target = "index.cgi" %] |
| 30 | +[% END %] |
| 31 | + |
| 32 | +[%# If SSL is in use, use 'sslbase', else use 'urlbase'. %] |
| 33 | +[% IF Param("sslbase") != "" && Param("ssl") != "never" %] |
| 34 | + [% login_target = Param("sslbase") _ login_target %] |
| 35 | +[% ELSE %] |
| 36 | + [% login_target = Param("urlbase") _ login_target %] |
| 37 | +[% END %] |
| 38 | + |
| 39 | +<li id="mini_login_container[% qs_suffix %]"> |
| 40 | + <a id="login_link[% qs_suffix %]" href="?GoAheadAndLogIn=1" |
| 41 | + onclick="return show_mini_login_form('[% qs_suffix %]')">Log In</a> |
| 42 | + <form action="[% login_target FILTER html %]" method="POST" |
| 43 | + class="mini_login bz_default_hidden" |
| 44 | + id="mini_login[% qs_suffix FILTER html %]" |
| 45 | + onsubmit="return check_mini_login_fields( '[% qs_suffix FILTER html %]' );" |
| 46 | + > |
| 47 | + <input id="Bugzilla_login[% qs_suffix FILTER html %]" |
| 48 | + class="bz_login" |
| 49 | + name="Bugzilla_login" |
| 50 | + onfocus="mini_login_on_focus('[% qs_suffix FILTER js %]')" |
| 51 | + > |
| 52 | + <input class="bz_password" |
| 53 | + id="Bugzilla_password[% qs_suffix FILTER html %]" |
| 54 | + name="Bugzilla_password" |
| 55 | + type="password" |
| 56 | + > |
| 57 | + <input class="bz_password bz_default_hidden bz_mini_login_help" type="text" |
| 58 | + id="Bugzilla_password_dummy[% qs_suffix %]" value="password" |
| 59 | + onfocus="mini_login_on_focus('[% qs_suffix FILTER js %]')" |
| 60 | + > |
| 61 | + [% IF Param('rememberlogin') == 'defaulton' || |
| 62 | + Param('rememberlogin') == 'defaultoff' |
| 63 | + %] |
| 64 | + <input type="checkbox" id="Bugzilla_remember[% qs_suffix %]" |
| 65 | + name="Bugzilla_remember" value="on" class="bz_remember" |
| 66 | + [%+ "checked" IF Param('rememberlogin') == "defaulton" %]> |
| 67 | + <label for="Bugzilla_remember[% qs_suffix %]">Remember</label> |
| 68 | + [% END %] |
| 69 | + <input type="submit" name="GoAheadAndLogIn" value="Log in" |
| 70 | + id="log_in[% qs_suffix %]"> |
| 71 | + <script type="text/javascript"> |
| 72 | + mini_login_constants = { |
| 73 | + "login" : "login", |
| 74 | + "warning" : "You must set the login and password before logging in." |
| 75 | + }; |
| 76 | + [%# We need this event to fire after autocomplete, because it does |
| 77 | + # something different depending on whether or not there's already |
| 78 | + # data in the login and password box. |
| 79 | + # However, autocomplete happens at all sorts of different times in |
| 80 | + # different browsers (before or after onDOMReady, before or after |
| 81 | + # window.onload, in almost all combinations you can imagine). |
| 82 | + # The only good solution I found is to time the event 200 |
| 83 | + # milliseconds after window.onload for WebKit (doing it immediately |
| 84 | + # at onload works in Chrome but not in Safari, but I can't detect |
| 85 | + # them separately using YUI), and right after onDOMReady in Gecko. |
| 86 | + # The WebKit solution is also fairly guaranteed to work on any |
| 87 | + # browser (it's just strange, since the fields only populate 200 ms |
| 88 | + # after the page loads), so it's the default. IE doesn't even |
| 89 | + # recognize our forms as login forms, so I made it use the Gecko |
| 90 | + # method also (since it's nicer visually). Opera never autocompletes |
| 91 | + # forms without user interaction, so it also uses the Gecko method. |
| 92 | + #%] |
| 93 | + if (YAHOO.env.ua.gecko || YAHOO.env.ua.ie || YAHOO.env.ua.opera) { |
| 94 | + YAHOO.util.Event.onDOMReady(function() { |
| 95 | + init_mini_login_form('[% qs_suffix FILTER html %]'); |
| 96 | + }); |
| 97 | + } |
| 98 | + else { |
| 99 | + YAHOO.util.Event.on(window, 'load', function () { |
| 100 | + window.setTimeout(function() { |
| 101 | + init_mini_login_form('[% qs_suffix FILTER html %]'); |
| 102 | + }, 200); |
| 103 | + }); |
| 104 | + } |
| 105 | + </script> |
| 106 | + <a href="#" onclick="return hide_mini_login_form('[% qs_suffix %]')">[x]</a> |
| 107 | + </form> |
| 108 | +</li> |
| 109 | +<li id="forgot_container[% qs_suffix %]"> |
| 110 | + <a id="forgot_link[% qs_suffix %]" href="?GoAheadAndLogIn=1#forgot" |
| 111 | + onclick="return show_forgot_form('[% qs_suffix %]')">Forgot Password</a> |
| 112 | + <form action="token.cgi" method="post" id="forgot_form[% qs_suffix %]" |
| 113 | + class="mini_forgot bz_default_hidden"> |
| 114 | + <label>Login: <input type="text" name="loginname" size="20"></label> |
| 115 | + <input id="forgot_button[% qs_suffix %]" value="Reset Password" |
| 116 | + type="submit"> |
| 117 | + <input type="hidden" name="a" value="reqpw"> |
| 118 | + <a href="#" onclick="return hide_forgot_form('[% qs_suffix %]')">[x]</a> |
| 119 | + </form> |
| 120 | +</li> |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/bug/edit.html.tmpl |
— | — | @@ -0,0 +1,1164 @@ |
| 2 | +[%# The contents of this file are subject to the Mozilla Public |
| 3 | + # License Version 1.1 (the "License"); you may not use this file |
| 4 | + # except in compliance with the License. You may obtain a copy of |
| 5 | + # the License at http://www.mozilla.org/MPL/ |
| 6 | + # |
| 7 | + # Software distributed under the License is distributed on an "AS |
| 8 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + # implied. See the License for the specific language governing |
| 10 | + # rights and limitations under the License. |
| 11 | + # |
| 12 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + # |
| 14 | + # The Initial Developer of the Original Code is Netscape Communications |
| 15 | + # Corporation. Portions created by Netscape are |
| 16 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + # Rights Reserved. |
| 18 | + # |
| 19 | + # Contributor(s): Gervase Markham <gerv@gerv.net> |
| 20 | + # Vaskin Kissoyan <vkissoyan@yahoo.com> |
| 21 | + # Max Kanat-Alexander <mkanat@bugzilla.org> |
| 22 | + # Frédéric Buclin <LpSolit@gmail.com> |
| 23 | + # Olav Vitters <olav@bkor.dhs.org> |
| 24 | + # Guy Pyrzak <guy.pyrzak@gmail.com> |
| 25 | + # Elliotte Martin <emartin@everythingsolved.com> |
| 26 | + #%] |
| 27 | +[%### The only customization to this template is to move the comment_box below the comments --pdhanda ###%] |
| 28 | + |
| 29 | +[% PROCESS global/variables.none.tmpl %] |
| 30 | + |
| 31 | +[% PROCESS "global/field-descs.none.tmpl" %] |
| 32 | + |
| 33 | +[% PROCESS bug/time.html.tmpl %] |
| 34 | + |
| 35 | +[% USE Bugzilla %] |
| 36 | +[% SET select_fields = {} %] |
| 37 | +[% FOREACH field = Bugzilla.get_fields( |
| 38 | + { type => constants.FIELD_TYPE_SINGLE_SELECT, custom => 0 }) |
| 39 | +%] |
| 40 | + [% select_fields.${field.name} = field %] |
| 41 | +[% END %] |
| 42 | + |
| 43 | + <script type="text/javascript"> |
| 44 | + <!-- |
| 45 | + |
| 46 | + /* Outputs a link to call replyToComment(); used to reduce HTML output */ |
| 47 | + function addReplyLink(id, real_id) { |
| 48 | + /* XXX this should really be updated to use the DOM Core's |
| 49 | + * createElement, but finding a container isn't trivial. |
| 50 | + */ |
| 51 | + [% IF user.settings.quote_replies.value != 'off' %] |
| 52 | + document.write('[<a href="#add_comment" onclick="replyToComment(' + |
| 53 | + id + ',' + real_id + '); return false;">reply<' + '/a>]'); |
| 54 | + [% END %] |
| 55 | + } |
| 56 | + |
| 57 | + /* Adds the reply text to the `comment' textarea */ |
| 58 | + function replyToComment(id, real_id) { |
| 59 | + var prefix = "(In reply to comment #" + id + ")\n"; |
| 60 | + var replytext = ""; |
| 61 | + [% IF user.settings.quote_replies.value == 'quoted_reply' %] |
| 62 | + /* pre id="comment_name_N" */ |
| 63 | + var text_elem = document.getElementById('comment_text_'+id); |
| 64 | + var text = getText(text_elem); |
| 65 | + |
| 66 | + /* make sure we split on all newlines -- IE or Moz use \r and \n |
| 67 | + * respectively. |
| 68 | + */ |
| 69 | + text = text.split(/\r|\n/); |
| 70 | + |
| 71 | + for (var i=0; i < text.length; i++) { |
| 72 | + replytext += "> " + text[i] + "\n"; |
| 73 | + } |
| 74 | + |
| 75 | + replytext = prefix + replytext + "\n"; |
| 76 | + [% ELSIF user.settings.quote_replies.value == 'simple_reply' %] |
| 77 | + replytext = prefix; |
| 78 | + [% END %] |
| 79 | + |
| 80 | + [% IF user.is_insider %] |
| 81 | + if (document.getElementById('isprivate_' + real_id).checked) { |
| 82 | + document.getElementById('newcommentprivacy').checked = 'checked'; |
| 83 | + } |
| 84 | + [% END %] |
| 85 | + |
| 86 | + /* <textarea id="comment"> */ |
| 87 | + var textarea = document.getElementById('comment'); |
| 88 | + textarea.value += replytext; |
| 89 | + |
| 90 | + textarea.focus(); |
| 91 | + } |
| 92 | + |
| 93 | + if (typeof Node == 'undefined') { |
| 94 | + /* MSIE doesn't define Node, so provide a compatibility object */ |
| 95 | + window.Node = { |
| 96 | + TEXT_NODE: 3, |
| 97 | + ENTITY_REFERENCE_NODE: 5 |
| 98 | + }; |
| 99 | + } |
| 100 | + |
| 101 | + /* Concatenates all text from element's childNodes. This is used |
| 102 | + * instead of innerHTML because we want the actual text (and |
| 103 | + * innerText is non-standard). |
| 104 | + */ |
| 105 | + function getText(element) { |
| 106 | + var child, text = ""; |
| 107 | + for (var i=0; i < element.childNodes.length; i++) { |
| 108 | + child = element.childNodes[i]; |
| 109 | + var type = child.nodeType; |
| 110 | + if (type == Node.TEXT_NODE || type == Node.ENTITY_REFERENCE_NODE) { |
| 111 | + text += child.nodeValue; |
| 112 | + } else { |
| 113 | + /* recurse into nodes of other types */ |
| 114 | + text += getText(child); |
| 115 | + } |
| 116 | + } |
| 117 | + return text; |
| 118 | + } |
| 119 | + |
| 120 | +[% IF user.is_timetracker %] |
| 121 | + var fRemainingTime = [% bug.remaining_time %]; // holds the original value |
| 122 | + function adjustRemainingTime() { |
| 123 | + // subtracts time spent from remaining time |
| 124 | + var new_time; |
| 125 | + |
| 126 | + // prevent negative values if work_time > fRemainingTime |
| 127 | + new_time = |
| 128 | + Math.max(fRemainingTime - document.changeform.work_time.value, 0.0); |
| 129 | + // get upto 2 decimal places |
| 130 | + document.changeform.remaining_time.value = |
| 131 | + Math.round(new_time * 100)/100; |
| 132 | + } |
| 133 | + |
| 134 | + function updateRemainingTime() { |
| 135 | + // if the remaining time is changed manually, update fRemainingTime |
| 136 | + fRemainingTime = document.changeform.remaining_time.value; |
| 137 | + } |
| 138 | + |
| 139 | +[% END %] |
| 140 | + |
| 141 | + //--> |
| 142 | + </script> |
| 143 | + |
| 144 | +<form name="changeform" method="post" action="process_bug.cgi"> |
| 145 | + |
| 146 | + <input type="hidden" name="delta_ts" value="[% bug.delta_ts %]"> |
| 147 | + <input type="hidden" name="longdesclength" value="[% bug.comments.size %]"> |
| 148 | + <input type="hidden" name="id" value="[% bug.bug_id %]"> |
| 149 | + <input type="hidden" name="token" value="[% issue_hash_token([bug.id, bug.delta_ts]) FILTER html %]"> |
| 150 | + |
| 151 | + [% PROCESS section_title %] |
| 152 | + <table class="edit_form"> |
| 153 | + <tr> |
| 154 | + [%# 1st Column %] |
| 155 | + <td id="bz_show_bug_column_1" class="bz_show_bug_column"> |
| 156 | + <table> |
| 157 | + [%# *** ID, product, component, status, resolution, Hardware, and OS *** %] |
| 158 | + [% PROCESS section_status %] |
| 159 | + |
| 160 | + [% PROCESS section_spacer %] |
| 161 | + |
| 162 | + [% PROCESS section_details1 %] |
| 163 | + |
| 164 | + [% PROCESS section_spacer %] |
| 165 | + |
| 166 | + [%# *** severity, priority, version and milestone *** %] |
| 167 | + [% PROCESS section_details2 %] |
| 168 | + |
| 169 | + [%# *** assigned to and qa contact *** %] |
| 170 | + [% PROCESS section_people %] |
| 171 | + |
| 172 | + [% PROCESS section_spacer %] |
| 173 | + |
| 174 | + [% PROCESS section_url_keyword_whiteboard %] |
| 175 | + |
| 176 | + [% PROCESS section_spacer %] |
| 177 | + |
| 178 | + [%# *** Dependencies *** %] |
| 179 | + [% PROCESS section_dependson_blocks %] |
| 180 | + |
| 181 | + </table> |
| 182 | + </td> |
| 183 | + <td> |
| 184 | + <div class="bz_column_spacer"> </div> |
| 185 | + </td> |
| 186 | + [%# 2nd Column %] |
| 187 | + <td id="bz_show_bug_column_2" class="bz_show_bug_column"> |
| 188 | + <table cellpadding="3" cellspacing="1"> |
| 189 | + [%# *** Reported and modified dates *** %] |
| 190 | + [% PROCESS section_dates %] |
| 191 | + |
| 192 | + [% PROCESS section_cclist %] |
| 193 | + |
| 194 | + [% PROCESS section_spacer %] |
| 195 | + |
| 196 | + [% PROCESS section_see_also %] |
| 197 | + |
| 198 | + [% PROCESS section_customfields %] |
| 199 | + |
| 200 | + [% PROCESS section_spacer %] |
| 201 | + |
| 202 | + [% Hook.process("after_custom_fields") %] |
| 203 | + |
| 204 | + [% PROCESS section_flags %] |
| 205 | + |
| 206 | + </table> |
| 207 | + </td> |
| 208 | + </tr> |
| 209 | + <tr> |
| 210 | + <td colspan="3"> |
| 211 | + <hr id="bz_top_half_spacer"> |
| 212 | + </td> |
| 213 | + </tr> |
| 214 | + </table> |
| 215 | + |
| 216 | + <table id="bz_big_form_parts" cellspacing="0" cellpadding="0"><tr> |
| 217 | + <td> |
| 218 | + [% IF user.is_timetracker %] |
| 219 | + [% PROCESS section_timetracking %] |
| 220 | + [% END %] |
| 221 | + |
| 222 | + [%# *** Attachments *** %] |
| 223 | + |
| 224 | + [% PROCESS attachment/list.html.tmpl |
| 225 | + attachments = bug.attachments |
| 226 | + bugid = bug.bug_id |
| 227 | + num_attachment_flag_types = bug.num_attachment_flag_types |
| 228 | + show_attachment_flags = bug.show_attachment_flags |
| 229 | + %] |
| 230 | + |
| 231 | + </td> |
| 232 | + <td> |
| 233 | + [% PROCESS section_restrict_visibility %] |
| 234 | + </td> |
| 235 | + </tr></table> |
| 236 | + |
| 237 | + [%# *** Additional Comments *** %] |
| 238 | + <div id="comments"> |
| 239 | + [% PROCESS bug/comments.html.tmpl |
| 240 | + comments = bug.comments |
| 241 | + mode = user.id ? "edit" : "show" |
| 242 | + %] |
| 243 | + </div> |
| 244 | + |
| 245 | +[%### The only customization to this template is to move the comment_box below the comments --pdhanda ###%] |
| 246 | +[% PROCESS comment_box %] |
| 247 | + |
| 248 | +</form> |
| 249 | + |
| 250 | +[%############################################################################%] |
| 251 | +[%# Block for the Title (alias and short desc) #%] |
| 252 | +[%############################################################################%] |
| 253 | + |
| 254 | +[% BLOCK section_title %] |
| 255 | + [%# That's the main table, which contains all editable fields. %] |
| 256 | + <div class="bz_alias_short_desc_container edit_form"> |
| 257 | + [% PROCESS commit_button id="_top"%] |
| 258 | + <a href="show_bug.cgi?id=[% bug.bug_id %]"> |
| 259 | + [%-# %]<b>[% terms.Bug %] [% bug.bug_id FILTER html %]</b> |
| 260 | + [%-# %]</a> -<span id="summary_alias_container" class="bz_default_hidden"> |
| 261 | + [% IF Param("usebugaliases") %] |
| 262 | + [% IF bug.alias != "" %] |
| 263 | + (<span id="alias_nonedit_display">[% bug.alias FILTER html %]</span>) |
| 264 | + [% END %] |
| 265 | + [% END %] |
| 266 | + <span id="short_desc_nonedit_display">[% bug.short_desc FILTER quoteUrls(bug) %]</span> |
| 267 | + [% IF bug.check_can_change_field('short_desc', 0, 1) || |
| 268 | + bug.check_can_change_field('alias', 0, 1) %] |
| 269 | + <small class="editme">(<a href="#" id="editme_action">edit</a>)</small> |
| 270 | + [% END %] |
| 271 | + </span> |
| 272 | + |
| 273 | + |
| 274 | + <div id="summary_alias_input"> |
| 275 | + <table id="summary"> |
| 276 | + [% IF Param("usebugaliases") %] |
| 277 | + <tr> |
| 278 | + [% IF bug.check_can_change_field('alias', 0, 1) %] |
| 279 | + <td> |
| 280 | + <label |
| 281 | + for="alias" |
| 282 | + title="a name for the |
| 283 | + [% terms.bug %] that can be used in place of its ID number, |
| 284 | + [%%] e.g. when adding it to a list of dependencies" |
| 285 | + >Alias</label>:</td><td> |
| 286 | + [% ELSIF bug.alias %] |
| 287 | + <td colspan="2">( |
| 288 | + [% ELSE %] |
| 289 | + <td colspan="2"> |
| 290 | + [% END %] |
| 291 | + [% PROCESS input inputname => "alias" |
| 292 | + size => "20" |
| 293 | + maxlength => "20" |
| 294 | + no_td => 1 |
| 295 | + %][% ")" IF NOT bug.check_can_change_field('alias', 0, 1) |
| 296 | + && bug.alias %] |
| 297 | + </td> |
| 298 | + </tr> |
| 299 | + [% END %] |
| 300 | + [%# *** Summary *** %] |
| 301 | + <tr> |
| 302 | + <td> |
| 303 | + <label accesskey="s" for="short_desc"><u>S</u>ummary</label>: |
| 304 | + </td> |
| 305 | + <td> |
| 306 | + [% PROCESS input inputname => "short_desc" size => "80" colspan => 2 |
| 307 | + maxlength => 255 spellcheck => "true" no_td => 1 %] |
| 308 | + </td> |
| 309 | + </tr> |
| 310 | + </table> |
| 311 | + </div> |
| 312 | + </div> |
| 313 | + <script type="text/javascript"> |
| 314 | + hideAliasAndSummary('[% bug.short_desc FILTER js %]', '[% bug.alias FILTER js %]'); |
| 315 | + </script> |
| 316 | +[% END %] |
| 317 | + |
| 318 | +[%############################################################################%] |
| 319 | +[%# Block for the first table in the "Details" section #%] |
| 320 | +[%############################################################################%] |
| 321 | + |
| 322 | +[% BLOCK section_details1 %] |
| 323 | + |
| 324 | + [%#############%] |
| 325 | + [%# PRODUCT #%] |
| 326 | + [%#############%] |
| 327 | + |
| 328 | + <tr> |
| 329 | + [% INCLUDE bug/field.html.tmpl |
| 330 | + bug = bug, field = select_fields.product, |
| 331 | + override_legal_values = bug.choices.product |
| 332 | + desc_url = 'describecomponents.cgi', value = bug.product |
| 333 | + editable = bug.check_can_change_field('product', 0, 1) %] |
| 334 | + </tr> |
| 335 | + [%###############%] |
| 336 | + [%# Component #%] |
| 337 | + [%###############%] |
| 338 | + <tr> |
| 339 | + <td class="field_label"> |
| 340 | + <label for="component" accesskey="m"> |
| 341 | + <b><a href="describecomponents.cgi?product=[% bug.product FILTER url_quote %]"> |
| 342 | + Co<u>m</u>ponent</a>: |
| 343 | + </b> |
| 344 | + </label> |
| 345 | + </td> |
| 346 | + [% PROCESS select selname => "component" %] |
| 347 | + </tr> |
| 348 | + <tr> |
| 349 | + <td class="field_label"> |
| 350 | + <label for="version"><b>Version</b></label>: |
| 351 | + </td> |
| 352 | + |
| 353 | + [% PROCESS select selname => "version" %] |
| 354 | + </tr> |
| 355 | + [%############%] |
| 356 | + [%# PLATFORM #%] |
| 357 | + [%############%] |
| 358 | + <tr> |
| 359 | + <td class="field_label"> |
| 360 | + <label for="rep_platform" accesskey="h"><b>Platform</b></label>: |
| 361 | + </td> |
| 362 | + <td class="field_value"> |
| 363 | + [% INCLUDE bug/field.html.tmpl |
| 364 | + bug = bug, field = select_fields.rep_platform, |
| 365 | + no_tds = 1, value = bug.rep_platform |
| 366 | + editable = bug.check_can_change_field('rep_platform', 0, 1) %] |
| 367 | + [%+ INCLUDE bug/field.html.tmpl |
| 368 | + bug = bug, field = select_fields.op_sys, |
| 369 | + no_tds = 1, value = bug.op_sys |
| 370 | + editable = bug.check_can_change_field('op_sys', 0, 1) %] |
| 371 | + <script type="text/javascript"> |
| 372 | + assignToDefaultOnChange(['product', 'component']); |
| 373 | + </script> |
| 374 | + </td> |
| 375 | + </tr> |
| 376 | + |
| 377 | + |
| 378 | + |
| 379 | +[% END %] |
| 380 | + |
| 381 | +[%############################################################################%] |
| 382 | +[%# Block for the status section #%] |
| 383 | +[%############################################################################%] |
| 384 | + |
| 385 | +[% BLOCK section_status %] |
| 386 | + <tr> |
| 387 | + <td class="field_label"> |
| 388 | + <b><a href="page.cgi?id=fields.html#status">Status</a></b>: |
| 389 | + </td> |
| 390 | + <td id="bz_field_status"> |
| 391 | + <span id="static_bug_status"> |
| 392 | + [% display_value("bug_status", bug.bug_status) FILTER html %] |
| 393 | + [% IF bug.resolution %] |
| 394 | + [%+ display_value("resolution", bug.resolution) FILTER html %] |
| 395 | + [% IF bug.dup_id %] |
| 396 | + of [% "${terms.bug} ${bug.dup_id}" FILTER bug_link(bug.dup_id) FILTER none %] |
| 397 | + [% END %] |
| 398 | + [% END %] |
| 399 | + [% IF bug.user.canedit || bug.user.isreporter %] |
| 400 | + (<a href="#add_comment" |
| 401 | + onclick="window.setTimeout(function() { document.getElementById('bug_status').focus(); }, 10)">edit</a>) |
| 402 | + [% END %] |
| 403 | + </span> |
| 404 | + </td> |
| 405 | + </tr> |
| 406 | +[% END %] |
| 407 | + |
| 408 | +[%############################################################################%] |
| 409 | +[%# Block for the second table in the "Details" section #%] |
| 410 | +[%############################################################################%] |
| 411 | + |
| 412 | +[% BLOCK section_details2 %] |
| 413 | + |
| 414 | + [%###############################################################%] |
| 415 | + [%# Importance (priority, severity and votes) #%] |
| 416 | + [%###############################################################%] |
| 417 | + <tr> |
| 418 | + <td class="field_label"> |
| 419 | + <label for="priority" accesskey="i"> |
| 420 | + <b><a href="page.cgi?id=fields.html#importance"><u>I</u>mportance</a></b></label>: |
| 421 | + </td> |
| 422 | + <td> |
| 423 | + [% INCLUDE bug/field.html.tmpl |
| 424 | + bug = bug, field = select_fields.priority, |
| 425 | + no_tds = 1, value = bug.priority |
| 426 | + editable = bug.check_can_change_field('priority', 0, 1) %] |
| 427 | + [%+ INCLUDE bug/field.html.tmpl |
| 428 | + bug = bug, field = select_fields.bug_severity, |
| 429 | + no_tds = 1, value = bug.bug_severity |
| 430 | + editable = bug.check_can_change_field('bug_severity', 0, 1) %] |
| 431 | + [% IF bug.use_votes %] |
| 432 | + <span id="votes_container"> |
| 433 | + [% IF bug.votes %] |
| 434 | + with |
| 435 | + <a href="votes.cgi?action=show_bug&bug_id=[% bug.bug_id %]"> |
| 436 | + [% bug.votes %] |
| 437 | + [% IF bug.votes == 1 %] |
| 438 | + vote |
| 439 | + [% ELSE %] |
| 440 | + votes |
| 441 | + [% END %]</a> |
| 442 | + [% END %] |
| 443 | + (<a href="votes.cgi?action=show_user&bug_id= |
| 444 | + [% bug.bug_id %]#vote_[% bug.bug_id %]">vote</a>) |
| 445 | + </span> |
| 446 | + [% END %] |
| 447 | + </td> |
| 448 | + </tr> |
| 449 | + |
| 450 | + [% IF Param("usetargetmilestone") && bug.target_milestone %] |
| 451 | + <tr> |
| 452 | + <td class="field_label"> |
| 453 | + <label for="target_milestone"> |
| 454 | + <a href="page.cgi?id=fields.html#target_milestone"> |
| 455 | + Target Milestone</a></label>: |
| 456 | + </td> |
| 457 | + [% PROCESS select selname = "target_milestone" %] |
| 458 | + </tr> |
| 459 | + [% END %] |
| 460 | + |
| 461 | +[% END %] |
| 462 | + |
| 463 | +[%############################################################################%] |
| 464 | +[%# Block for the table in the "People" section #%] |
| 465 | +[%############################################################################%] |
| 466 | + |
| 467 | +[% BLOCK section_people %] |
| 468 | + |
| 469 | + <tr> |
| 470 | + <td class="field_label"> |
| 471 | + <b><a href="page.cgi?id=fields.html#assigned_to">Assigned To</a></b>: |
| 472 | + </td> |
| 473 | + <td> |
| 474 | + [% IF bug.check_can_change_field("assigned_to", 0, 1) %] |
| 475 | + <div id="bz_assignee_edit_container" class="bz_default_hidden"> |
| 476 | + <span> |
| 477 | + [% INCLUDE global/user.html.tmpl who = bug.assigned_to %] |
| 478 | + (<a href="#" id="bz_assignee_edit_action">edit</a>) |
| 479 | + </span> |
| 480 | + </div> |
| 481 | + <div id="bz_assignee_input"> |
| 482 | + [% INCLUDE global/userselect.html.tmpl |
| 483 | + id => "assigned_to" |
| 484 | + name => "assigned_to" |
| 485 | + value => bug.assigned_to.login |
| 486 | + size => 30 |
| 487 | + %] |
| 488 | + <br> |
| 489 | + <input type="checkbox" id="set_default_assignee" name="set_default_assignee" value="1"> |
| 490 | + <label id="set_default_assignee_label" for="set_default_assignee">Reset Assignee to default</label> |
| 491 | + </div> |
| 492 | + <script type="text/javascript"> |
| 493 | + hideEditableField('bz_assignee_edit_container', |
| 494 | + 'bz_assignee_input', |
| 495 | + 'bz_assignee_edit_action', |
| 496 | + 'assigned_to', |
| 497 | + '[% bug.assigned_to.login FILTER js %]' ); |
| 498 | + initDefaultCheckbox('assignee'); |
| 499 | + </script> |
| 500 | + [% ELSE %] |
| 501 | + [% INCLUDE global/user.html.tmpl who = bug.assigned_to %] |
| 502 | + [% END %] |
| 503 | + </td> |
| 504 | + </tr> |
| 505 | + |
| 506 | + [% IF Param('useqacontact') %] |
| 507 | + <tr> |
| 508 | + <td class="field_label"> |
| 509 | + <label for="qa_contact" accesskey="q"><b><u>Q</u>A Contact</b></label>: |
| 510 | + </td> |
| 511 | + <td> |
| 512 | + [% IF bug.check_can_change_field("qa_contact", 0, 1) %] |
| 513 | + [% IF bug.qa_contact != "" %] |
| 514 | + <div id="bz_qa_contact_edit_container" class="bz_default_hidden"> |
| 515 | + <span> |
| 516 | + <span id="bz_qa_contact_edit_display"> |
| 517 | + [% INCLUDE global/user.html.tmpl who = bug.qa_contact %]</span> |
| 518 | + (<a href="#" id="bz_qa_contact_edit_action">edit</a>) |
| 519 | + </span> |
| 520 | + </div> |
| 521 | + [% END %] |
| 522 | + <div id="bz_qa_contact_input"> |
| 523 | + [% INCLUDE global/userselect.html.tmpl |
| 524 | + id => "qa_contact" |
| 525 | + name => "qa_contact" |
| 526 | + value => bug.qa_contact.login |
| 527 | + size => 30 |
| 528 | + emptyok => 1 |
| 529 | + %] |
| 530 | + <br> |
| 531 | + <input type="checkbox" id="set_default_qa_contact" name="set_default_qa_contact" value="1"> |
| 532 | + <label for="set_default_qa_contact" id="set_default_qa_contact_label">Reset QA Contact to default</label> |
| 533 | + </div> |
| 534 | + <script type="text/javascript"> |
| 535 | + [% IF bug.qa_contact != "" %] |
| 536 | + hideEditableField('bz_qa_contact_edit_container', |
| 537 | + 'bz_qa_contact_input', |
| 538 | + 'bz_qa_contact_edit_action', |
| 539 | + 'qa_contact', |
| 540 | + '[% bug.qa_contact.login FILTER js %]'); |
| 541 | + [% END %] |
| 542 | + initDefaultCheckbox('qa_contact'); |
| 543 | + </script> |
| 544 | + [% ELSE %] |
| 545 | + [% INCLUDE global/user.html.tmpl who = bug.qa_contact %] |
| 546 | + [% END %] |
| 547 | + </td> |
| 548 | + </tr> |
| 549 | + [% END %] |
| 550 | +[% END %] |
| 551 | + |
| 552 | +[%############################################################################%] |
| 553 | +[%# Block for URL Keyword and Whiteboard #%] |
| 554 | +[%############################################################################%] |
| 555 | +[% BLOCK section_url_keyword_whiteboard %] |
| 556 | +[%# *** URL Whiteboard Keywords *** %] |
| 557 | + <tr> |
| 558 | + <td class="field_label"> |
| 559 | + <label for="bug_file_loc" accesskey="u"><b> |
| 560 | + [% IF bug.bug_file_loc |
| 561 | + AND NOT bug.bug_file_loc.match("^(javascript|data)") %] |
| 562 | + <a href="[% bug.bug_file_loc FILTER html %]"><u>U</u>RL</a> |
| 563 | + [% ELSE %] |
| 564 | + <u>U</u>RL |
| 565 | + [% END %] |
| 566 | + [%%]</b></label>: |
| 567 | + </td> |
| 568 | + <td> |
| 569 | + [% IF bug.check_can_change_field("bug_file_loc", 0, 1) %] |
| 570 | + <span id="bz_url_edit_container" class="bz_default_hidden"> |
| 571 | + [% IF bug.bug_file_loc |
| 572 | + AND NOT bug.bug_file_loc.match("^(javascript|data)") %] |
| 573 | + <a href="[% bug.bug_file_loc FILTER html %]" target="_blank" |
| 574 | + title="[% bug.bug_file_loc FILTER html %]"> |
| 575 | + [% bug.bug_file_loc FILTER truncate(40) FILTER html %]</a> |
| 576 | + [% ELSE %] |
| 577 | + [% bug.bug_file_loc FILTER html %] |
| 578 | + [% END %] |
| 579 | + (<a href="#" id="bz_url_edit_action">edit</a>)</span> |
| 580 | + [% END %] |
| 581 | + <span id="bz_url_input_area"> |
| 582 | + [% url_output = PROCESS input no_td=1 inputname => "bug_file_loc" size => "40" colspan => 2 %] |
| 583 | + [% IF NOT bug.check_can_change_field("bug_file_loc", 0, 1) %] |
| 584 | + <a href="[% bug.bug_file_loc FILTER html %]">[% url_output FILTER none %]</a> |
| 585 | + [% ELSE %] |
| 586 | + [% url_output FILTER none %] |
| 587 | + [% END %] |
| 588 | + </span> |
| 589 | + [% IF bug.check_can_change_field("bug_file_loc", 0, 1) %] |
| 590 | + <script type="text/javascript"> |
| 591 | + hideEditableField('bz_url_edit_container', |
| 592 | + 'bz_url_input_area', |
| 593 | + 'bz_url_edit_action', |
| 594 | + 'bug_file_loc', |
| 595 | + "[% bug.bug_file_loc FILTER js %]"); |
| 596 | + </script> |
| 597 | + [% END %] |
| 598 | + </td> |
| 599 | + </tr> |
| 600 | + |
| 601 | + [% IF Param('usestatuswhiteboard') %] |
| 602 | + <tr> |
| 603 | + <td class="field_label"> |
| 604 | + <label for="status_whiteboard" accesskey="w"><b><u>W</u>hiteboard</b></label>: |
| 605 | + </td> |
| 606 | + [% PROCESS input inputname => "status_whiteboard" size => "40" colspan => 2 %] |
| 607 | + </tr> |
| 608 | + [% END %] |
| 609 | + |
| 610 | + [% IF use_keywords %] |
| 611 | + <tr> |
| 612 | + <td class="field_label"> |
| 613 | + <label for="keywords" accesskey="k"> |
| 614 | + <b><a href="describekeywords.cgi"><u>K</u>eywords</a></b></label>: |
| 615 | + </td> |
| 616 | + [% PROCESS input inputname => "keywords" size => 40 colspan => 2 |
| 617 | + value => bug.keywords.join(', ') %] |
| 618 | + </tr> |
| 619 | + [% END %] |
| 620 | +[% END %] |
| 621 | + |
| 622 | +[%############################################################################%] |
| 623 | +[%# Block for Depends On / Blocks #%] |
| 624 | +[%############################################################################%] |
| 625 | +[% BLOCK section_dependson_blocks %] |
| 626 | + <tr> |
| 627 | + [% PROCESS dependencies |
| 628 | + dep = { title => "Depends on", fieldname => "dependson" } %] |
| 629 | + </tr> |
| 630 | + |
| 631 | + <tr> |
| 632 | + [% PROCESS dependencies accesskey = "b" |
| 633 | + dep = { title => "<u>B</u>locks", fieldname => "blocked" } %] |
| 634 | + |
| 635 | + <tr> |
| 636 | + <th> </th> |
| 637 | + |
| 638 | + <td colspan="2" align="left" id="show_dependency_tree_or_graph"> |
| 639 | + Show dependency <a href="showdependencytree.cgi?id=[% bug.bug_id %]&hide_resolved=1">tree</a> |
| 640 | + |
| 641 | + [% IF Param('webdotbase') %] |
| 642 | + / <a href="showdependencygraph.cgi?id=[% bug.bug_id %]">graph</a> |
| 643 | + [% END %] |
| 644 | + </td> |
| 645 | + </tr> |
| 646 | +[% END %] |
| 647 | + |
| 648 | + |
| 649 | +[%############################################################################%] |
| 650 | +[%# Block for Restricting Visibility #%] |
| 651 | +[%############################################################################%] |
| 652 | + |
| 653 | +[% BLOCK section_restrict_visibility %] |
| 654 | + [% RETURN UNLESS bug.groups.size %] |
| 655 | + |
| 656 | + <div class="bz_group_visibility_section"> |
| 657 | + [% inallgroups = 1 %] |
| 658 | + [% inagroup = 0 %] |
| 659 | + [% emitted_description = 0 %] |
| 660 | + |
| 661 | + [% FOREACH group = bug.groups %] |
| 662 | + [% SET inallgroups = 0 IF NOT group.ingroup %] |
| 663 | + [% SET inagroup = 1 IF group.ison %] |
| 664 | + |
| 665 | + [% NEXT IF group.mandatory %] |
| 666 | + |
| 667 | + [% IF NOT emitted_description %] |
| 668 | + [% emitted_description = 1 %] |
| 669 | + <div id="bz_restrict_group_visibility_help"> |
| 670 | + <b>Only users in all of the selected groups can view this |
| 671 | + [%+ terms.bug %]:</b> |
| 672 | + <p class="instructions"> |
| 673 | + Unchecking all boxes makes this a more public [% terms.bug %]. |
| 674 | + </p> |
| 675 | + </div> |
| 676 | + [% END %] |
| 677 | + |
| 678 | + [% IF group.ingroup %] |
| 679 | + <input type="hidden" name="defined_bit-[% group.bit %]" value="1"> |
| 680 | + [% END %] |
| 681 | + |
| 682 | + <input type="checkbox" value="1" name="bit-[% group.bit %]" |
| 683 | + id="bit-[% group.bit %]" |
| 684 | + [% ' checked="checked"' IF group.ison %] |
| 685 | + [% ' disabled="disabled"' IF NOT group.ingroup %]> |
| 686 | + <label for="bit-[% group.bit %]"> |
| 687 | + [%- group.description FILTER html_light %]</label> |
| 688 | + <br> |
| 689 | + [% END %] |
| 690 | + |
| 691 | + [% IF emitted_description %] |
| 692 | + [% IF NOT inallgroups %] |
| 693 | + <p class="instructions">Only members of a group can change the |
| 694 | + visibility of [% terms.abug %] for that group.</p> |
| 695 | + [% END %] |
| 696 | + [% END %] |
| 697 | + |
| 698 | + [% IF inagroup %] |
| 699 | + <div id="bz_enable_role_visibility_help"> |
| 700 | + <b>Users in the roles selected below can always view |
| 701 | + this [% terms.bug %]:</b> |
| 702 | + </div> |
| 703 | + <div id="bz_enable_role_visibility"> |
| 704 | + <div> |
| 705 | + [% user_can_edit_accessible = |
| 706 | + bug.check_can_change_field("reporter_accessible", 0, 1) |
| 707 | + %] |
| 708 | + [% IF user_can_edit_accessible %] |
| 709 | + <input type="hidden" name="defined_reporter_accessible" value="1"> |
| 710 | + [% END %] |
| 711 | + <input type="checkbox" value="1" |
| 712 | + name="reporter_accessible" id="reporter_accessible" |
| 713 | + [% " checked" IF bug.reporter_accessible %] |
| 714 | + [% " disabled=\"disabled\"" UNLESS user_can_edit_accessible %]> |
| 715 | + <label for="reporter_accessible">Reporter</label> |
| 716 | + </div> |
| 717 | + <div> |
| 718 | + [% user_can_edit_accessible = |
| 719 | + bug.check_can_change_field("cclist_accessible", 0, 1) |
| 720 | + %] |
| 721 | + [% IF user_can_edit_accessible %] |
| 722 | + <input type="hidden" name="defined_cclist_accessible" value="1"> |
| 723 | + [% END %] |
| 724 | + <input type="checkbox" value="1" |
| 725 | + name="cclist_accessible" id="cclist_accessible" |
| 726 | + [% " checked" IF bug.cclist_accessible %] |
| 727 | + [% " disabled=\"disabled\"" UNLESS user_can_edit_accessible %]> |
| 728 | + <label for="cclist_accessible">CC List</label> |
| 729 | + </div> |
| 730 | + <p class="instructions"> |
| 731 | + The assignee |
| 732 | + [% IF (Param('useqacontact')) %] |
| 733 | + and QA contact |
| 734 | + [% END %] |
| 735 | + can always see [% terms.abug %], and this section does not |
| 736 | + take effect unless the [% terms.bug %] is restricted to at |
| 737 | + least one group. |
| 738 | + </p> |
| 739 | + </div> |
| 740 | + [% END %] |
| 741 | + </div> [%# bz_group_visibility_section %] |
| 742 | +[% END %] |
| 743 | + |
| 744 | +[%############################################################################%] |
| 745 | +[%# Block for Dates #%] |
| 746 | +[%############################################################################%] |
| 747 | + |
| 748 | +[% BLOCK section_dates %] |
| 749 | + <tr> |
| 750 | + <td class="field_label"> |
| 751 | + <b>Reported</b>: |
| 752 | + </td> |
| 753 | + <td> |
| 754 | + [% bug.creation_ts FILTER time %] by [% INCLUDE global/user.html.tmpl who = bug.reporter %] |
| 755 | + </td> |
| 756 | + </tr> |
| 757 | + |
| 758 | + <tr> |
| 759 | + <td class="field_label"> |
| 760 | + <b> Modified</b>: |
| 761 | + </td> |
| 762 | + <td> |
| 763 | + [% bug.delta_ts FILTER time FILTER replace(':\d\d$', '') FILTER replace(':\d\d ', ' ')%] |
| 764 | + (<a href="show_activity.cgi?id=[% bug.bug_id %]">[%# terms.Bug %]History</a>) |
| 765 | + </td> |
| 766 | + |
| 767 | + </tr> |
| 768 | +[% END %] |
| 769 | + |
| 770 | +[%############################################################################%] |
| 771 | +[%# Block for CC LIST #%] |
| 772 | +[%############################################################################%] |
| 773 | +[% BLOCK section_cclist %] |
| 774 | + <tr> |
| 775 | + <td class="field_label"> |
| 776 | + <label for="newcc" accesskey="a"><b>CC List</b>:</label> |
| 777 | + </td> |
| 778 | + <td> |
| 779 | + [% IF user.id %] |
| 780 | + [% IF NOT bug.cc || NOT bug.cc.contains(user.login) %] |
| 781 | + [% has_role = bug.user.isreporter |
| 782 | + || bug.assigned_to.id == user.id |
| 783 | + || (Param('useqacontact') |
| 784 | + && bug.qa_contact |
| 785 | + && bug.qa_contact.id == user.id) %] |
| 786 | + <input type="checkbox" id="addselfcc" name="addselfcc" |
| 787 | + [% " checked=\"checked\"" |
| 788 | + IF user.settings.state_addselfcc.value == 'always' |
| 789 | + || (!has_role |
| 790 | + && user.settings.state_addselfcc.value == 'cc_unless_role') %]> |
| 791 | + <label for="addselfcc">Add me to CC list</label> |
| 792 | + <br> |
| 793 | + [% END %] |
| 794 | + [% END %] |
| 795 | + [% bug.cc.size || 0 FILTER html %] |
| 796 | + [% IF bug.cc.size == 1 %] |
| 797 | + user |
| 798 | + [% ELSE %] |
| 799 | + users |
| 800 | + [% END %] |
| 801 | + [% IF user.id %] |
| 802 | + [% IF bug.cc.contains( user.email ) %] |
| 803 | + including you |
| 804 | + [% END %] |
| 805 | + [% END %] |
| 806 | + <span id="cc_edit_area_showhide_container" class="bz_default_hidden"> |
| 807 | + (<a href="#" id="cc_edit_area_showhide">[% IF user.id %]edit[% ELSE %]show[% END %]</a>) |
| 808 | + </span> |
| 809 | + <div id="cc_edit_area"> |
| 810 | + <br> |
| 811 | + [% IF user.id %] |
| 812 | + <div> |
| 813 | + <div><label for="cc"><b>Add</b></label></div> |
| 814 | + [% INCLUDE global/userselect.html.tmpl |
| 815 | + id => "newcc" |
| 816 | + name => "newcc" |
| 817 | + value => "" |
| 818 | + size => 30 |
| 819 | + multiple => 5 |
| 820 | + %] |
| 821 | + </div> |
| 822 | + [% END %] |
| 823 | + [% IF bug.cc %] |
| 824 | + <select id="cc" name="cc" multiple="multiple" size="5"> |
| 825 | + [% FOREACH c = bug.cc %] |
| 826 | + <option value="[% c FILTER email FILTER html %]"> |
| 827 | + [% c FILTER email FILTER html %]</option> |
| 828 | + [% END %] |
| 829 | + </select> |
| 830 | + [% IF user.id %] |
| 831 | + <br> |
| 832 | + <input type="checkbox" id="removecc" name="removecc"> |
| 833 | + [%%]<label for="removecc">Remove selected CCs</label> |
| 834 | + <br> |
| 835 | + [% END %] |
| 836 | + [% END %] |
| 837 | + </div> |
| 838 | + <script type="text/javascript"> |
| 839 | + hideEditableField( 'cc_edit_area_showhide_container', |
| 840 | + 'cc_edit_area', |
| 841 | + 'cc_edit_area_showhide', |
| 842 | + '', |
| 843 | + ''); |
| 844 | + </script> |
| 845 | + </td> |
| 846 | + </tr> |
| 847 | +[% END %] |
| 848 | + |
| 849 | +[%############################################################################%] |
| 850 | +[%# Block for See Also #%] |
| 851 | +[%############################################################################%] |
| 852 | +[% BLOCK section_see_also %] |
| 853 | + [% IF Param('use_see_also') || bug.see_also.size %] |
| 854 | + <tr> |
| 855 | + [% INCLUDE bug/field.html.tmpl |
| 856 | + field = bug_fields.see_also |
| 857 | + value = bug.see_also |
| 858 | + editable = bug.check_can_change_field('see_also', 0, 1) |
| 859 | + %] |
| 860 | + </tr> |
| 861 | + [% END %] |
| 862 | +[% END %] |
| 863 | + |
| 864 | +[%############################################################################%] |
| 865 | +[%# Block for FLAGS #%] |
| 866 | +[%############################################################################%] |
| 867 | + |
| 868 | +[% BLOCK section_flags %] |
| 869 | + [%# *** Flags *** %] |
| 870 | + [% show_bug_flags = 0 %] |
| 871 | + [% FOREACH type = bug.flag_types %] |
| 872 | + [% IF (type.flags && type.flags.size > 0) || (user.id && type.is_active) %] |
| 873 | + [% show_bug_flags = 1 %] |
| 874 | + [% LAST %] |
| 875 | + [% END %] |
| 876 | + [% END %] |
| 877 | + [% IF show_bug_flags %] |
| 878 | + <tr> |
| 879 | + <td class="field_label flags_label"> |
| 880 | + <label><b>Flags:</b></label> |
| 881 | + </td> |
| 882 | + <td></td> |
| 883 | + </tr> |
| 884 | + <tr> |
| 885 | + <td colspan="2"> |
| 886 | + [% IF bug.flag_types.size > 0 %] |
| 887 | + [% PROCESS "flag/list.html.tmpl" flag_no_header = 1 |
| 888 | + flag_types = bug.flag_types |
| 889 | + any_flags_requesteeble = bug.any_flags_requesteeble %] |
| 890 | + [% END %] |
| 891 | + </td> |
| 892 | + </tr> |
| 893 | + [% END %] |
| 894 | +[% END %] |
| 895 | + |
| 896 | +[%############################################################################%] |
| 897 | +[%# Block for Custom Fields #%] |
| 898 | +[%############################################################################%] |
| 899 | + |
| 900 | +[% BLOCK section_customfields %] |
| 901 | +[%# *** Custom Fields *** %] |
| 902 | + |
| 903 | + [% FOREACH field = Bugzilla.active_custom_fields %] |
| 904 | + <tr> |
| 905 | + [% PROCESS bug/field.html.tmpl value=bug.${field.name} |
| 906 | + editable = bug.check_can_change_field(field.name, 0, 1) |
| 907 | + value_span = 2 %] |
| 908 | + </tr> |
| 909 | + [% END %] |
| 910 | +[% END %] |
| 911 | + |
| 912 | +[%############################################################################%] |
| 913 | +[%# Block for Section Spacer #%] |
| 914 | +[%############################################################################%] |
| 915 | + |
| 916 | +[% BLOCK section_spacer %] |
| 917 | + <tr> |
| 918 | + <td colspan="2" class="bz_section_spacer"></td> |
| 919 | + </tr> |
| 920 | +[% END %] |
| 921 | + |
| 922 | + |
| 923 | + |
| 924 | + |
| 925 | +[%############################################################################%] |
| 926 | +[%# Block for dependencies #%] |
| 927 | +[%############################################################################%] |
| 928 | + |
| 929 | +[% BLOCK dependencies %] |
| 930 | + |
| 931 | + <th class="field_label"> |
| 932 | + <label for="[% dep.fieldname %]"[% " accesskey=\"$accesskey\"" IF accesskey %]> |
| 933 | + [% dep.title %]</label>: |
| 934 | + </th> |
| 935 | + <td> |
| 936 | + <span id="[% dep.fieldname %]_input_area"> |
| 937 | + [% IF bug.check_can_change_field(dep.fieldname, 0, 1) %] |
| 938 | + <input name="[% dep.fieldname %]" id="[% dep.fieldname %]" |
| 939 | + class="text_input" |
| 940 | + value="[% bug.${dep.fieldname}.join(', ') %]"> |
| 941 | + [% END %] |
| 942 | + </span> |
| 943 | + |
| 944 | + [% FOREACH depbug = bug.${dep.fieldname} %] |
| 945 | + [% depbug FILTER bug_link(depbug, use_alias => 1) FILTER none %][% " " %] |
| 946 | + [% END %] |
| 947 | + [% IF bug.check_can_change_field(dep.fieldname, 0, 1) %] |
| 948 | + <span id="[% dep.fieldname %]_edit_container" class="edit_me bz_default_hidden" > |
| 949 | + (<a href="#" id="[% dep.fieldname %]_edit_action">edit</a>) |
| 950 | + </span> |
| 951 | + <script type="text/javascript"> |
| 952 | + hideEditableField('[% dep.fieldname %]_edit_container', |
| 953 | + '[% dep.fieldname %]_input_area', |
| 954 | + '[% dep.fieldname %]_edit_action', |
| 955 | + '[% dep.fieldname %]', |
| 956 | + "[% bug.${dep.fieldname}.join(', ') %]"); |
| 957 | + </script> |
| 958 | + [% END %] |
| 959 | + </td> |
| 960 | + |
| 961 | + [% accesskey = undef %] |
| 962 | + |
| 963 | +[% END %] |
| 964 | + |
| 965 | +[%############################################################################%] |
| 966 | +[%# Block for Time Tracking Group #%] |
| 967 | +[%############################################################################%] |
| 968 | + |
| 969 | +[% BLOCK section_timetracking %] |
| 970 | + <table class="bz_time_tracking_table"> |
| 971 | + <tr> |
| 972 | + <th> |
| 973 | + <label for="estimated_time">Orig. Est.</label> |
| 974 | + </th> |
| 975 | + <th> |
| 976 | + Current Est. |
| 977 | + </th> |
| 978 | + <th> |
| 979 | + <label for="work_time">Hours Worked</label> |
| 980 | + </th> |
| 981 | + <th> |
| 982 | + <label for="remaining_time">Hours Left</label> |
| 983 | + </th> |
| 984 | + <th> |
| 985 | + %Complete |
| 986 | + </th> |
| 987 | + <th> |
| 988 | + Gain |
| 989 | + </th> |
| 990 | + <th> |
| 991 | + <label for="deadline">Deadline</label> |
| 992 | + </th> |
| 993 | + </tr> |
| 994 | + <tr> |
| 995 | + <td> |
| 996 | + <input name="estimated_time" id="estimated_time" |
| 997 | + value="[% PROCESS formattimeunit |
| 998 | + time_unit=bug.estimated_time %]" |
| 999 | + size="6" maxlength="6"> |
| 1000 | + </td> |
| 1001 | + <td> |
| 1002 | + [% PROCESS formattimeunit |
| 1003 | + time_unit=(bug.actual_time + bug.remaining_time) %] |
| 1004 | + </td> |
| 1005 | + <td> |
| 1006 | + [% PROCESS formattimeunit time_unit=bug.actual_time %] + |
| 1007 | + <input name="work_time" id="work_time" |
| 1008 | + value="0" size="3" maxlength="6" |
| 1009 | + onchange="adjustRemainingTime();"> |
| 1010 | + </td> |
| 1011 | + <td> |
| 1012 | + <input name="remaining_time" id="remaining_time" |
| 1013 | + value="[% PROCESS formattimeunit |
| 1014 | + time_unit=bug.remaining_time %]" |
| 1015 | + size="6" maxlength="6" onchange="updateRemainingTime();"> |
| 1016 | + </td> |
| 1017 | + <td> |
| 1018 | + [% PROCESS calculatepercentage act=bug.actual_time |
| 1019 | + rem=bug.remaining_time %] |
| 1020 | + </td> |
| 1021 | + <td> |
| 1022 | + [% PROCESS formattimeunit time_unit=bug.estimated_time - (bug.actual_time + bug.remaining_time) %] |
| 1023 | + </td> |
| 1024 | + <td> |
| 1025 | + <input name="deadline" id="deadline" value="[% bug.deadline %]" |
| 1026 | + size="10" maxlength="10"><br /> |
| 1027 | + <small>(YYYY-MM-DD)</small> |
| 1028 | + </td> |
| 1029 | + </tr> |
| 1030 | + <tr> |
| 1031 | + <td colspan="7" class="bz_summarize_time"> |
| 1032 | + <a href="summarize_time.cgi?id=[% bug.bug_id %]&do_depends=1"> |
| 1033 | + Summarize time (including time for [% terms.bugs %] |
| 1034 | + blocking this [% terms.bug %])</a> |
| 1035 | + </td> |
| 1036 | + </tr> |
| 1037 | + </table> |
| 1038 | +[% END %] |
| 1039 | + |
| 1040 | +[%############################################################################%] |
| 1041 | +[%# Block for the Additional Comments box #%] |
| 1042 | +[%############################################################################%] |
| 1043 | + |
| 1044 | +[% BLOCK comment_box %] |
| 1045 | + <div class="bz_section_additional_comments"> |
| 1046 | + <a name="add_comment"></a> |
| 1047 | + [% IF user.id %] |
| 1048 | + <label for="comment" accesskey="c"><b>Additional |
| 1049 | + <u>C</u>omments</b></label>: |
| 1050 | + |
| 1051 | + [% IF user.is_insider %] |
| 1052 | + <input type="checkbox" name="commentprivacy" value="1" |
| 1053 | + id="newcommentprivacy" |
| 1054 | + onClick="updateCommentTagControl(this, form)"> |
| 1055 | + <label for="newcommentprivacy"> |
| 1056 | + Make comment private (visible only to members of the |
| 1057 | + <strong>[% Param('insidergroup') FILTER html %]</strong> group) |
| 1058 | + </label> |
| 1059 | + [% END %] |
| 1060 | + |
| 1061 | + <!-- This table keeps the submit button aligned with the box. --> |
| 1062 | + <table><tr><td> |
| 1063 | + [% INCLUDE global/textarea.html.tmpl |
| 1064 | + name = 'comment' |
| 1065 | + id = 'comment' |
| 1066 | + minrows = 10 |
| 1067 | + maxrows = 25 |
| 1068 | + cols = constants.COMMENT_COLS |
| 1069 | + %] |
| 1070 | + [% Hook.process("after_comment_textarea", 'bug/edit.html.tmpl') %] |
| 1071 | + <br> |
| 1072 | + [% PROCESS commit_button id=""%] |
| 1073 | + |
| 1074 | + <table class="status" cellspacing="0" cellpadding="0"> |
| 1075 | + <tr> |
| 1076 | + <td class="field_label"> |
| 1077 | + <b><a href="page.cgi?id=fields.html#status">Status</a></b>: |
| 1078 | + </td> |
| 1079 | + <td> |
| 1080 | + <a name="bug_status_bottom"></a> |
| 1081 | + [% PROCESS bug/knob.html.tmpl %] |
| 1082 | + </td> |
| 1083 | + </tr> |
| 1084 | + </table> |
| 1085 | + </td></tr></table> |
| 1086 | + |
| 1087 | + [%# For logged-out users %] |
| 1088 | + [% ELSE %] |
| 1089 | + <table><tr><td><fieldset> |
| 1090 | + <legend>Note</legend> |
| 1091 | + You need to |
| 1092 | + <a href="show_bug.cgi?id= |
| 1093 | + [%- bug.bug_id %]&GoAheadAndLogIn=1">log in</a> |
| 1094 | + before you can comment on or make changes to this [% terms.bug %]. |
| 1095 | + </fieldset></table><tr></td> |
| 1096 | + [% END %] |
| 1097 | + </div> |
| 1098 | +[% END %] |
| 1099 | + |
| 1100 | +[%############################################################################%] |
| 1101 | +[%# Block for SELECT fields #%] |
| 1102 | +[%############################################################################%] |
| 1103 | + |
| 1104 | +[% BLOCK select %] |
| 1105 | + <td> |
| 1106 | + [% IF bug.check_can_change_field(selname, 0, 1) |
| 1107 | + AND bug.choices.${selname}.size > 1 %] |
| 1108 | + <select id="[% selname %]" name="[% selname %]"> |
| 1109 | + [% FOREACH x = bug.choices.${selname} %] |
| 1110 | + <option value="[% x.name FILTER html %]" |
| 1111 | + [% " selected" IF x.name == bug.${selname} %]> |
| 1112 | + [%- x.name FILTER html %] |
| 1113 | + </option> |
| 1114 | + [% END %] |
| 1115 | + </select> |
| 1116 | + [% ELSE %] |
| 1117 | + [% bug.${selname} FILTER html %] |
| 1118 | + [% END %] |
| 1119 | + </td> |
| 1120 | +[% END %] |
| 1121 | + |
| 1122 | +[%############################################################################%] |
| 1123 | +[%# Block for INPUT fields #%] |
| 1124 | +[%############################################################################%] |
| 1125 | + |
| 1126 | +[% BLOCK input %] |
| 1127 | + [% IF no_td != 1 %] |
| 1128 | + <td[% " colspan=\"$colspan\"" IF colspan %]> |
| 1129 | + [% END %] |
| 1130 | + [% val = value ? value : bug.$inputname %] |
| 1131 | + [% IF bug.check_can_change_field(inputname, 0, 1) %] |
| 1132 | + <input id="[% inputname %]" name="[% inputname %]" class="text_input" |
| 1133 | + value="[% val FILTER html %]"[% " size=\"$size\"" IF size %] |
| 1134 | + [% " maxlength=\"$maxlength\"" IF maxlength %] |
| 1135 | + [% " spellcheck=\"$spellcheck\"" IF spellcheck %]> |
| 1136 | + [% ELSE %] |
| 1137 | + [% IF size && val.length > size %] |
| 1138 | + <span title="[% val FILTER html %]"> |
| 1139 | + [% val FILTER truncate(size) FILTER html %] |
| 1140 | + </span> |
| 1141 | + [% ELSE %] |
| 1142 | + [% val FILTER html %] |
| 1143 | + [% END %] |
| 1144 | + [% END %] |
| 1145 | + [% IF no_td != 1 %] |
| 1146 | + </td> |
| 1147 | + [% END %] |
| 1148 | + [% no_td = 0 %] |
| 1149 | + [% maxlength = 0 %] |
| 1150 | + [% colspan = 0 %] |
| 1151 | + [% size = 0 %] |
| 1152 | + [% value = undef %] |
| 1153 | + [% spellcheck = undef %] |
| 1154 | +[% END %] |
| 1155 | +[% BLOCK commit_button %] |
| 1156 | + [% IF user.id %] |
| 1157 | + <div class="knob-buttons"> |
| 1158 | + <input type="submit" value="Save Changes" |
| 1159 | + id="commit[% id FILTER css_class_quote %]"> |
| 1160 | + [% IF bug.user.canmove %] |
| 1161 | + <input type="submit" name="action" id="action[% id FILTER css_class_quote %]" value="[% Param("move-button-text") %]"> |
| 1162 | + [% END %] |
| 1163 | + </div> |
| 1164 | + [% END %] |
| 1165 | +[% END %] |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/bug/activity/table.html.tmpl |
— | — | @@ -0,0 +1,117 @@ |
| 2 | +[%# The contents of this file are subject to the Mozilla Public |
| 3 | + # License Version 1.1 (the "License"); you may not use this file |
| 4 | + # except in compliance with the License. You may obtain a copy of |
| 5 | + # the License at http://www.mozilla.org/MPL/ |
| 6 | + # |
| 7 | + # Software distributed under the License is distributed on an "AS |
| 8 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + # implied. See the License for the specific language governing |
| 10 | + # rights and limitations under the License. |
| 11 | + # |
| 12 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + # |
| 14 | + # The Initial Developer of the Original Code is Netscape Communications |
| 15 | + # Corporation. Portions created by Netscape are |
| 16 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + # Rights Reserved. |
| 18 | + # |
| 19 | + # Contributor(s): Gervase Markham <gerv@gerv.net> |
| 20 | + # David D. Kilzer <ddkilzer@kilzer.net> |
| 21 | + # Reed Loden <reed@reedloden.com> |
| 22 | + # |
| 23 | + # |
| 24 | + # |
| 25 | + # The only customization to this template is the addition of the bz_bugzctivity class --pdhanda |
| 26 | + #%] |
| 27 | + |
| 28 | +[%# INTERFACE: |
| 29 | + # operations: array of hashes. May be empty. Each has has three members: |
| 30 | + # who: string. who performed the operation |
| 31 | + # when: string. when they performed it |
| 32 | + # changes: hash. Details of what they changed. This hash has three |
| 33 | + # compulsory and one optional member: |
| 34 | + # field: string. The name of the field |
| 35 | + # removed: string. What was removed from the field |
| 36 | + # added: string. What was added to the field |
| 37 | + # attach_id: integer. If the change was adding an attachment, its id. |
| 38 | + # incomplete_data: boolean. True if some of the data is incomplete (because |
| 39 | + # it was affected by an old Bugzilla bug.) |
| 40 | + #%] |
| 41 | + |
| 42 | +[% PROCESS "global/field-descs.none.tmpl" %] |
| 43 | + |
| 44 | +[% PROCESS bug/time.html.tmpl %] |
| 45 | + |
| 46 | +[% IF incomplete_data %] |
| 47 | + <p> |
| 48 | + There used to be an issue in <a href="http://www.bugzilla.org/">Bugzilla</a> |
| 49 | + which caused activity data to be lost if there were a large number of cc's |
| 50 | + or dependencies. That has been fixed, but some data was already lost in |
| 51 | + your activity table that could not be regenerated. The changes that the |
| 52 | + script could not reliably determine are prefixed by '?'. |
| 53 | + </p> |
| 54 | +[% END %] |
| 55 | + |
| 56 | +[% IF operations.size > 0 %] |
| 57 | + <table class="bz_bugactivity"> |
| 58 | + <tr> |
| 59 | + <th>Who</th> |
| 60 | + <th>When</th> |
| 61 | + <th>What</th> |
| 62 | + <th>Removed</th> |
| 63 | + <th>Added</th> |
| 64 | + </tr> |
| 65 | + |
| 66 | + [% FOREACH operation = operations %] |
| 67 | + <tr> |
| 68 | + <td rowspan="[% operation.changes.size %]" valign="top"> |
| 69 | + [% operation.who FILTER email FILTER html %] |
| 70 | + </td> |
| 71 | + <td rowspan="[% operation.changes.size %]" valign="top"> |
| 72 | + [% operation.when FILTER time %] |
| 73 | + </td> |
| 74 | + [% FOREACH change = operation.changes %] |
| 75 | + [% "</tr><tr>" IF loop.index > 0 %] |
| 76 | + <td> |
| 77 | + [% IF change.attachid %] |
| 78 | + <a href="attachment.cgi?id=[% change.attachid %]"> |
| 79 | + Attachment #[% change.attachid %]</a> |
| 80 | + [% END %] |
| 81 | + [%+ field_descs.${change.fieldname} FILTER html %] |
| 82 | + </td> |
| 83 | + [% PROCESS change_column change_type = change.removed %] |
| 84 | + [% PROCESS change_column change_type = change.added %] |
| 85 | + [% END %] |
| 86 | + </tr> |
| 87 | + [% END %] |
| 88 | + </table> |
| 89 | +[% ELSE %] |
| 90 | + <p> |
| 91 | + No changes have been made to this [% terms.bug %] yet. |
| 92 | + </p> |
| 93 | +[% END %] |
| 94 | + |
| 95 | +[% BLOCK change_column %] |
| 96 | + <td> |
| 97 | + [% IF change_type.defined %] |
| 98 | + [% IF change.fieldname == 'estimated_time' || |
| 99 | + change.fieldname == 'remaining_time' || |
| 100 | + change.fieldname == 'work_time' %] |
| 101 | + [% PROCESS formattimeunit time_unit=change_type %] |
| 102 | + [% ELSIF change.fieldname == 'blocked' || |
| 103 | + change.fieldname == 'dependson' %] |
| 104 | + [% change_type FILTER bug_list_link FILTER none %] |
| 105 | + [% ELSIF change.fieldname == 'assigned_to' || |
| 106 | + change.fieldname == 'reporter' || |
| 107 | + change.fieldname == 'qa_contact' || |
| 108 | + change.fieldname == 'cc' || |
| 109 | + change.fieldname == 'flagtypes.name' %] |
| 110 | + [% display_value(change.fieldname, change_type) FILTER email FILTER html %] |
| 111 | + [% ELSE %] |
| 112 | + [% display_value(change.fieldname, change_type) FILTER html %] |
| 113 | + [% END %] |
| 114 | + [% ELSE %] |
| 115 | + |
| 116 | + [% END %] |
| 117 | + </td> |
| 118 | +[% END %] |
Index: trunk/tools/bugzilla/bugzilla-3.6.2/template/en/custom/bug/activity/show.html.tmpl |
— | — | @@ -0,0 +1,53 @@ |
| 2 | +[%# The contents of this file are subject to the Mozilla Public |
| 3 | + # License Version 1.1 (the "License"); you may not use this file |
| 4 | + # except in compliance with the License. You may obtain a copy of |
| 5 | + # the License at http://www.mozilla.org/MPL/ |
| 6 | + # |
| 7 | + # Software distributed under the License is distributed on an "AS |
| 8 | + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 9 | + # implied. See the License for the specific language governing |
| 10 | + # rights and limitations under the License. |
| 11 | + # |
| 12 | + # The Original Code is the Bugzilla Bug Tracking System. |
| 13 | + # |
| 14 | + # The Initial Developer of the Original Code is Netscape Communications |
| 15 | + # Corporation. Portions created by Netscape are |
| 16 | + # Copyright (C) 1998 Netscape Communications Corporation. All |
| 17 | + # Rights Reserved. |
| 18 | + # |
| 19 | + # Contributor(s): Gervase Markham <gerv@gerv.net> |
| 20 | + # |
| 21 | + # |
| 22 | + # The only customization to this template is the addition of bug_activity.css --pdhanda |
| 23 | + #%] |
| 24 | + |
| 25 | +[%# INTERFACE: |
| 26 | + # bug: object. The bug whose activity is being displayed. |
| 27 | + # operations: array of hashes, see activity/table.html.tmpl. |
| 28 | + # |
| 29 | + # This template also needs to be called with the interface to the |
| 30 | + # activity/table.html.tmpl template fulfilled. |
| 31 | + #%] |
| 32 | + |
| 33 | +[% PROCESS global/variables.none.tmpl %] |
| 34 | + |
| 35 | +[% filtered_desc = bug.short_desc FILTER html %] |
| 36 | +[% PROCESS global/header.html.tmpl |
| 37 | + title = "Changes made to $terms.bug $bug.bug_id" |
| 38 | + header = "Activity log for $terms.bug $bug.bug_id: $filtered_desc" |
| 39 | + style_urls = [ "skins/standard/bug_activity.css" ] |
| 40 | + %] |
| 41 | + |
| 42 | +<p> |
| 43 | + [% "Back to $terms.bug $bug.bug_id" FILTER bug_link(bug) FILTER none %] |
| 44 | +</p> |
| 45 | + |
| 46 | +[% PROCESS bug/activity/table.html.tmpl %] |
| 47 | + |
| 48 | +[% IF operations.size > 0 %] |
| 49 | + <p> |
| 50 | + [% "Back to $terms.bug $bug.bug_id" FILTER bug_link(bug) FILTER none %] |
| 51 | + </p> |
| 52 | +[% END %] |
| 53 | + |
| 54 | +[% PROCESS global/footer.html.tmpl %] |