r79290 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r79289‎ | r79290 | r79291 >
Date:20:46, 30 December 2010
Author:reedy
Status:deferred
Tags:
Comment:
Move 3 bugzilla directories into bugzilla folder
Modified paths:
  • /trunk/tools/bugzilla-3.4.4 (deleted) (history)
  • /trunk/tools/bugzilla-3.6.2 (deleted) (history)
  • /trunk/tools/bugzilla-4.0 (deleted) (history)
  • /trunk/tools/bugzilla/bugzilla-3.4.4 (added) (history)
  • /trunk/tools/bugzilla/bugzilla-3.6.2 (added) (history)
  • /trunk/tools/bugzilla/bugzilla-4.0 (added) (history)

Diff [purge]

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
147 + 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
176 + 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
151 + 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
161 + 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
147 + 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
146 + 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
135 + native
Added: svn:executable
236 + *
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
1269 + native
Added: svn:executable
2270 + *
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
1117 + 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
143 + 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
130 + 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
154 + 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
136 + 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
139 + 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
1425 + 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
1520 + 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
2521 + 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
126 + 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
137 + 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
173 + 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
1136 + 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
148 + 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
151 + 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
252 + 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
353 + 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
454 + 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
555 + 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
656 + 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
757 + 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
858 + 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
140 + 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
196 + 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
1108 + 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
1105 + 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
2106 + 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
3107 + 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
4108 + 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
5109 + 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
6110 + 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
7111 + 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
8112 + 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
9113 + 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
10114 + 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
11115 + 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
12116 + 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
13117 + 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
14118 + 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
15119 + 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
16120 + 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
17121 + 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
18122 + 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
19123 + 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
20124 + 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
21125 + 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
22126 + 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
23127 + 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
24128 + 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
25129 + 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
26130 + 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
27131 + 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
28132 + 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
29133 + 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
30134 + 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
31135 + 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
32136 + 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
33137 + 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
34138 + 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
35139 + 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
36140 + 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
37141 + 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
38142 + 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
39143 + 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
19 + 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
210 + 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
311 + 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
412 + 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
513 + 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
163 + 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
264 + 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
365 + 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
466 + 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
567 + 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~^(&gt;.+)$~<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}&amp;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 "&lt;missing bug number&gt;";
 317+ }
 318+ my $quote_bug_num = html_quote($bug_num);
 319+ detaint_natural($bug_num) || return "&lt;invalid bug number: $quote_bug_num&gt;";
 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 &#013;
 525+ # See bugs 4928, 22983 and 32000 for more details
 526+ html_linebreak => sub {
 527+ my ($var) = @_;
 528+ $var =~ s/\r\n/\&#013;/g;
 529+ $var =~ s/\n\r/\&#013;/g;
 530+ $var =~ s/\r/\&#013;/g;
 531+ $var =~ s/\n/\&#013;/g;
 532+ return $var;
 533+ },
 534+
 535+ # Prevents line break on hyphens and whitespaces.
 536+ no_break => sub {
 537+ my ($var) = @_;
 538+ $var =~ s/ /\&nbsp;/g;
 539+ $var =~ s/-/\&#8209;/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/\@/\&#64;/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/\&#64;/@/g;
 700+ $var =~ s/\&lt;/</g;
 701+ $var =~ s/\&gt;/>/g;
 702+ $var =~ s/\&quot;/\"/g;
 703+ $var =~ s/\&amp;/\&/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
1950 + 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
1702 + 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 %]&amp;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&amp;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&amp;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&nbsp;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&nbsp;Searches"
 97+ title="[% q.name FILTER html %]"
 98+ href="buglist.cgi?cmdtype=runnamed&amp;namedcmd=[% q.name FILTER url_quote %]">
 99+ [% END %]
 100+
 101+ [% FOREACH q = user.queries_subscribed %]
 102+ <link rel="Saved&nbsp;Search"
 103+ title="[% q.name FILTER html %] ([% q.user.login FILTER html %])"
 104+ href="buglist.cgi?cmdtype=dorem&amp;remaction=run&amp;namedcmd=
 105+ [% q.name FILTER url_quote %]&amp;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
1129 + 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
112 + 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&amp;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&amp;remaction=run&amp;namedcmd=
 24+ [% q.name FILTER url_quote %]&amp;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
133 + 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
1147 + 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 %]&amp;requestee=
 7+ [% user.login FILTER url_quote %]&amp;do_union=1&amp;group=type&amp;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&nbsp;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
133 + 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">&nbsp;</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&nbsp;out</a></li>
 41+ [% ELSE %]
 42+ <li>Logged&nbsp;in&nbsp;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&nbsp;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
1128 + 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
1103 + 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
1301 + 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
1121 + 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">&nbsp;</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 %]&amp;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 %]&nbsp;[% 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&amp;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&amp;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&nbsp;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&nbsp;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>&nbsp;</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 %]&amp;hide_resolved=1">tree</a>
 702+
 703+ [% IF Param('webdotbase') %]
 704+ /&nbsp;<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 %]&amp;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
11181 + 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 &ndash; $filtered_desc"
 45+ header = "$terms.Bug&nbsp;$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
175 + 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
1269 + *
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
168 + 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
269 + 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
370 + 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
471 + 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
572 + 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
673 + 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
774 + 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
1119 + 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
2120 + 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
3121 + 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
4122 + 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
5123 + 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
6124 + 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
7125 + 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
8126 + 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
9127 + 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
10128 + 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
11129 + 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
12130 + 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
13131 + 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
14132 + 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
15133 + 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
16134 + 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
17135 + 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
18136 + 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
19137 + 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
20138 + 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
21139 + 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
22140 + 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
23141 + 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
24142 + 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
25143 + 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
26144 + 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
27145 + 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
28146 + 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
29147 + 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
30148 + 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
31149 + 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
32150 + 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
33151 + 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
34152 + 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
35153 + 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
36154 + 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
37155 + 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
38156 + 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
19 + 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
163 + 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
264 + 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
365 + 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
466 + 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~^(&gt;.+)$~<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 = '&amp;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}&amp;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 &#013;
 540+ # See bugs 4928, 22983 and 32000 for more details
 541+ html_linebreak => sub {
 542+ my ($var) = @_;
 543+ $var =~ s/\r\n/\&#013;/g;
 544+ $var =~ s/\n\r/\&#013;/g;
 545+ $var =~ s/\r/\&#013;/g;
 546+ $var =~ s/\n/\&#013;/g;
 547+ return $var;
 548+ },
 549+
 550+ # Prevents line break on hyphens and whitespaces.
 551+ no_break => sub {
 552+ my ($var) = @_;
 553+ $var =~ s/ /\&nbsp;/g;
 554+ $var =~ s/-/\&#8209;/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/\&#64;/@/g;
 683+ $var =~ s/\&lt;/</g;
 684+ $var =~ s/\&gt;/>/g;
 685+ $var =~ s/\&quot;/\"/g;
 686+ $var =~ s/\&amp;/\&/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 %]&amp;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&amp;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&amp;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&nbsp;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&nbsp;Searches"
 97+ title="[% q.name FILTER html %]"
 98+ href="buglist.cgi?cmdtype=runnamed&amp;namedcmd=[% q.name FILTER url_quote %]">
 99+ [% END %]
 100+
 101+ [% FOREACH q = user.queries_subscribed %]
 102+ <link rel="Saved&nbsp;Search"
 103+ title="[% q.name FILTER html %] ([% q.user.login FILTER html %])"
 104+ href="buglist.cgi?cmdtype=dorem&amp;remaction=run&amp;namedcmd=
 105+ [% q.name FILTER url_quote %]&amp;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&amp;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&amp;remaction=run&amp;namedcmd=
 24+ [% q.name FILTER url_quote %]&amp;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 %]&amp;requestee=
 7+ [% user.login FILTER url_quote %]&amp;do_union=1&amp;group=type&amp;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&nbsp;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">&nbsp;</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&nbsp;out</a></li>
 41+ [% ELSE %]
 42+ <li>Logged&nbsp;in&nbsp;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&nbsp;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">&nbsp;</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 %]&nbsp;[% 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&amp;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&amp;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&nbsp;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&nbsp;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>&nbsp;</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 %]&amp;hide_resolved=1">tree</a>
 640+
 641+ [% IF Param('webdotbase') %]
 642+ /&nbsp;<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 %]&amp;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 %]&amp;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+ &nbsp;
 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 %]

Status & tagging log