summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'extensions')
-rw-r--r--extensions/BMO/Extension.pm233
-rw-r--r--extensions/BMO/lib/Data.pm31
-rw-r--r--extensions/BMO/lib/FakeBug.pm2
-rw-r--r--extensions/BMO/lib/Reports.pm62
-rw-r--r--extensions/BMO/template/en/default/account/create.html.tmpl10
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-brownbag.html.tmpl35
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-itrequest.html.tmpl27
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-mktgevent.html.tmpl23
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-mozlist.html.tmpl26
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl31
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-presentation.html.tmpl4
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl30
-rw-r--r--extensions/BMO/template/en/default/bug/create/user-message.html.tmpl22
-rw-r--r--extensions/BMO/template/en/default/global/choose-product.html.tmpl5
-rw-r--r--extensions/BMO/template/en/default/hook/bug/create/create-guided-form.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl1
-rw-r--r--extensions/BMO/template/en/default/hook/global/header-additional_header.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/hook/global/user-error-auth_failure_object.html.tmpl3
-rw-r--r--extensions/BMO/template/en/default/hook/global/user-error-errors.html.tmpl19
-rw-r--r--extensions/BMO/template/en/default/hook/global/user-error.html.tmpl/auth_failure/permissions.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/hook/pages/fields-resolution.html.tmpl13
-rw-r--r--extensions/BMO/template/en/default/hook/reports/menu-end.html.tmpl6
-rw-r--r--extensions/BMO/template/en/default/list/list.microsummary.tmpl3
-rw-r--r--extensions/BMO/template/en/default/list/server-push.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/pages/etiquette.html.tmpl42
-rw-r--r--extensions/BMO/template/en/default/pages/group_admins.html.tmpl53
-rw-r--r--extensions/BMO/template/en/default/pages/triage_reports.html.tmpl6
-rw-r--r--extensions/BMO/template/en/default/pages/user_activity.html.tmpl8
-rw-r--r--extensions/BMO/web/js/edit_bug.js15
-rw-r--r--extensions/BMO/web/js/edituser_menu.js26
-rw-r--r--extensions/BMO/web/styles/reports.css37
-rw-r--r--extensions/BzAPI/template/en/default/config.json.tmpl21
-rw-r--r--extensions/ComponentWatching/template/en/default/account/prefs/component_watch.html.tmpl10
-rw-r--r--extensions/Example/Extension.pm36
-rw-r--r--extensions/Example/lib/Config.pm2
-rw-r--r--extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl30
-rw-r--r--extensions/GuidedBugEntry/web/js/guided.js4
-rw-r--r--extensions/GuidedBugEntry/web/style/guided.css2
-rw-r--r--extensions/InlineHistory/Config.pm31
-rw-r--r--extensions/InlineHistory/Extension.pm183
-rw-r--r--extensions/InlineHistory/README10
-rw-r--r--extensions/InlineHistory/template/en/default/hook/bug/comments-aftercomments.html.tmpl135
-rw-r--r--extensions/InlineHistory/template/en/default/hook/bug/show-header-end.html.tmpl33
-rw-r--r--extensions/InlineHistory/template/en/default/hook/global/setting-descs-settings.none.tmpl31
-rw-r--r--extensions/InlineHistory/web/inline-history.js396
-rw-r--r--extensions/InlineHistory/web/style.css54
-rw-r--r--extensions/REMO/Config.pm34
-rw-r--r--extensions/REMO/Extension.pm184
-rw-r--r--extensions/REMO/template/en/default/bug/create/comment-mozreps.txt.tmpl (renamed from extensions/BMO/template/en/default/bug/create/comment-mozreps.txt.tmpl)2
-rw-r--r--extensions/REMO/template/en/default/bug/create/comment-remo-budget.txt.tmpl (renamed from extensions/BMO/template/en/default/bug/create/comment-remo-budget.txt.tmpl)0
-rw-r--r--extensions/REMO/template/en/default/bug/create/comment-remo-swag.txt.tmpl (renamed from extensions/BMO/template/en/default/bug/create/comment-remo-swag.txt.tmpl)24
-rw-r--r--extensions/REMO/template/en/default/bug/create/create-mozreps.html.tmpl (renamed from extensions/BMO/template/en/default/bug/create/create-mozreps.html.tmpl)22
-rw-r--r--extensions/REMO/template/en/default/bug/create/create-remo-budget.html.tmpl (renamed from extensions/BMO/template/en/default/bug/create/create-remo-budget.html.tmpl)10
-rw-r--r--extensions/REMO/template/en/default/bug/create/create-remo-swag.html.tmpl (renamed from extensions/BMO/template/en/default/bug/create/create-remo-swag.html.tmpl)69
-rw-r--r--extensions/REMO/template/en/default/bug/create/created-mozreps.html.tmpl38
-rw-r--r--extensions/REMO/template/en/default/hook/global/user-error-errors.html.tmpl40
-rw-r--r--extensions/REMO/template/en/default/pages/comment-remo-form-payment.txt.tmpl (renamed from extensions/BMO/template/en/default/pages/comment-remo-form-payment.txt.tmpl)2
-rw-r--r--extensions/REMO/template/en/default/pages/remo-form-payment.html.tmpl (renamed from extensions/BMO/template/en/default/pages/remo-form-payment.html.tmpl)10
-rw-r--r--extensions/REMO/web/js/form_validate.js21
-rw-r--r--extensions/REMO/web/js/swag.js60
-rw-r--r--extensions/REMO/web/styles/moz_reps.css (renamed from extensions/BMO/web/styles/moz_reps.css)0
-rw-r--r--extensions/SecureMail/template/en/default/account/prefs/securemail.html.tmpl10
-rw-r--r--extensions/SecureMail/template/en/default/pages/securemail/help.html.tmpl8
-rw-r--r--extensions/SiteMapIndex/Extension.pm3
-rw-r--r--extensions/SiteMapIndex/lib/Util.pm4
-rw-r--r--extensions/Splinter/lib/Util.pm22
-rw-r--r--extensions/Splinter/template/en/default/pages/splinter.html.tmpl13
-rw-r--r--extensions/Splinter/template/en/default/pages/splinter/help.html.tmpl54
-rw-r--r--extensions/Splinter/web/splinter.css13
-rw-r--r--extensions/Splinter/web/splinter.js97
-rw-r--r--extensions/TagNewUsers/Extension.pm16
-rw-r--r--extensions/TagNewUsers/template/en/default/hook/bug/comments-user.html.tmpl4
-rw-r--r--extensions/TypeSniffer/Extension.pm24
-rw-r--r--extensions/Voting/Extension.pm38
-rw-r--r--extensions/Voting/template/en/default/hook/admin/products/updated-changes.html.tmpl14
-rw-r--r--extensions/Voting/template/en/default/hook/bug/edit-after_importance.html.tmpl3
-rw-r--r--extensions/Voting/template/en/default/pages/voting/user.html.tmpl11
77 files changed, 2051 insertions, 558 deletions
diff --git a/extensions/BMO/Extension.pm b/extensions/BMO/Extension.pm
index 79edaad3e..c800ade3d 100644
--- a/extensions/BMO/Extension.pm
+++ b/extensions/BMO/Extension.pm
@@ -42,6 +42,7 @@ use DateTime;
use Bugzilla::Extension::BMO::FakeBug;
use Bugzilla::Extension::BMO::Data qw($cf_visible_in_products
$cf_flags
+ $cf_disabled_flags
%group_to_cc_map
$blocking_trusted_setters
$blocking_trusted_requesters
@@ -51,7 +52,8 @@ use Bugzilla::Extension::BMO::Data qw($cf_visible_in_products
%always_fileable_group
%product_sec_groups);
use Bugzilla::Extension::BMO::Reports qw(user_activity_report
- triage_reports);
+ triage_reports
+ group_admins);
our $VERSION = '0.1';
@@ -69,6 +71,7 @@ sub template_before_process {
my $vars = $args->{'vars'};
$vars->{'cf_hidden_in_product'} = \&cf_hidden_in_product;
+ $vars->{'cf_flag_disabled'} = \&cf_flag_disabled;
if ($file =~ /^list\/list/) {
# Purpose: enable correct sorting of list table
@@ -155,8 +158,8 @@ sub page_before_template {
# that our hook template can see.
Bugzilla->request_cache->{'bmo_fields_page'} = 1;
}
- elsif ($page eq 'remo-form-payment.html') {
- _remo_form_payment($vars);
+ elsif ($page eq 'group_admins.html') {
+ group_admins($vars);
}
}
@@ -242,6 +245,13 @@ sub cf_hidden_in_product {
return 0;
}
+sub cf_flag_disabled {
+ my ($field_name, $bug) = @_;
+ return 0 unless grep { $field_name eq $_ } @$cf_disabled_flags;
+ my $value = $bug->{$field_name};
+ return $value eq '---' || $value eq '';
+}
+
# Purpose: CC certain email addresses on bugmail when a bug is added or
# removed from a particular group.
sub bugmail_recipients {
@@ -440,6 +450,19 @@ sub _link_hg {
return qq{<a href="https://hg.mozilla.org/$repo/rev/$id">$text</a>};
}
+sub _link_bzr {
+ my $args = shift;
+ my $preamble = html_quote($args->{matches}->[0]);
+ my $url = html_quote($args->{matches}->[1]);
+ my $text = html_quote($args->{matches}->[2]);
+ my $id = html_quote($args->{matches}->[3]);
+
+ $url =~ s/\s+$//;
+ $url =~ s/\/$//;
+
+ return qq{$preamble<a href="http://$url/revision/$id">$text</a>};
+}
+
sub bug_format_comment {
my ($self, $args) = @_;
my $regexes = $args->{'regexes'};
@@ -466,6 +489,13 @@ sub bug_format_comment {
replace => \&_link_svn
});
+ push (@$regexes, {
+ match => qr/\b(Committing\sto:\sbzr\+ssh:\/\/
+ (?:[^\@]+\@)?(bzr\.mozilla\.org[^\n]+)\n.*?\nCommitted\s)
+ (revision\s(\d+))\./sx,
+ replace => \&_link_bzr
+ });
+
# Note: for grouping in this regexp, always use non-capturing parentheses.
my $hgrepos = join('|', qw!(?:releases/)?comm-[\w.]+
(?:releases/)?mozilla-[\w.]+
@@ -597,146 +627,6 @@ sub install_update_db {
}
}
-sub _remo_form_payment {
- my ($vars) = @_;
- my $input = Bugzilla->input_params;
-
- my $user = Bugzilla->login(LOGIN_REQUIRED);
-
- if ($input->{'action'} eq 'commit') {
- my $template = Bugzilla->template;
- my $cgi = Bugzilla->cgi;
- my $dbh = Bugzilla->dbh;
-
- my $bug_id = $input->{'bug_id'};
- detaint_natural($bug_id);
- my $bug = Bugzilla::Bug->check($bug_id);
-
- # Detect if the user already used the same form to submit again
- my $token = trim($input->{'token'});
- if ($token) {
- my ($creator_id, $date, $old_attach_id) = Bugzilla::Token::GetTokenData($token);
- if (!$creator_id
- || $creator_id != $user->id
- || $old_attach_id !~ "^remo_form_payment:")
- {
- # The token is invalid.
- ThrowUserError('token_does_not_exist');
- }
-
- $old_attach_id =~ s/^remo_form_payment://;
- if ($old_attach_id) {
- ThrowUserError('remo_payment_cancel_dupe',
- { bugid => $bug_id, attachid => $old_attach_id });
- }
- }
-
- # Make sure the user can attach to this bug
- if (!$bug->user->{'canedit'}) {
- ThrowUserError("remo_payment_bug_edit_denied",
- { bug_id => $bug->id });
- }
-
- # Make sure the bug is under the correct product/component
- if ($bug->product ne 'Mozilla Reps'
- || $bug->component ne 'Budget Requests')
- {
- ThrowUserError('remo_payment_invalid_product');
- }
-
- my ($timestamp) = $dbh->selectrow_array("SELECT NOW()");
-
- $dbh->bz_start_transaction;
-
- # Create the comment to be added based on the form fields from rep-payment-form
- my $comment;
- $template->process("pages/comment-remo-form-payment.txt.tmpl", $vars, \$comment)
- || ThrowTemplateError($template->error());
- $bug->add_comment($comment, { isprivate => 0 });
-
- # Attach expense report
- # FIXME: Would be nice to be able to have the above prefilled comment and
- # the following attachments all show up under a single comment. But the longdescs
- # table can only handle one attach_id per comment currently. At least only one
- # email is sent the way it is done below.
- my $attachment;
- if (defined $cgi->upload('expenseform')) {
- # Determine content-type
- my $content_type = $cgi->uploadInfo($cgi->param('expenseform'))->{'Content-Type'};
-
- $attachment = Bugzilla::Attachment->create(
- { bug => $bug,
- creation_ts => $timestamp,
- data => $cgi->upload('expenseform'),
- description => 'Expense Form',
- filename => scalar $cgi->upload('expenseform'),
- ispatch => 0,
- isprivate => 0,
- isurl => 0,
- mimetype => $content_type,
- store_in_file => 0,
- });
-
- # Insert comment for attachment
- $bug->add_comment('', { isprivate => 0,
- type => CMT_ATTACHMENT_CREATED,
- extra_data => $attachment->id });
- }
-
- # Attach receipts file
- if (defined $cgi->upload("receipts")) {
- # Determine content-type
- my $content_type = $cgi->uploadInfo($cgi->param("receipts"))->{'Content-Type'};
-
- $attachment = Bugzilla::Attachment->create(
- { bug => $bug,
- creation_ts => $timestamp,
- data => $cgi->upload('receipts'),
- description => "Receipts",
- filename => scalar $cgi->upload("receipts"),
- ispatch => 0,
- isprivate => 0,
- isurl => 0,
- mimetype => $content_type,
- store_in_file => 0,
- });
-
- # Insert comment for attachment
- $bug->add_comment('', { isprivate => 0,
- type => CMT_ATTACHMENT_CREATED,
- extra_data => $attachment->id });
- }
-
- $bug->update($timestamp);
-
- if ($token) {
- trick_taint($token);
- $dbh->do('UPDATE tokens SET eventdata = ? WHERE token = ?', undef,
- ("remo_form_payment:" . $attachment->id, $token));
- }
-
- $dbh->bz_commit_transaction;
-
- # Define the variables and functions that will be passed to the UI template.
- $vars->{'attachment'} = $attachment;
- $vars->{'bugs'} = [ new Bugzilla::Bug($bug_id) ];
- $vars->{'header_done'} = 1;
- $vars->{'contenttypemethod'} = 'autodetect';
-
- my $recipients = { 'changer' => $user };
- $vars->{'sent_bugmail'} = Bugzilla::BugMail::Send($bug_id, $recipients);
-
- print $cgi->header();
- # Generate and return the UI (HTML page) from the appropriate template.
- $template->process("attachment/created.html.tmpl", $vars)
- || ThrowTemplateError($template->error());
- exit;
- }
- else {
- $vars->{'token'} = issue_session_token('remo_form_payment:');
- }
-}
-
sub _last_closed_date {
my ($self) = @_;
my $dbh = Bugzilla->dbh;
@@ -796,4 +686,61 @@ sub webservice {
$dispatch->{BMO} = "Bugzilla::Extension::BMO::WebService";
}
+our $search_content_matches;
+BEGIN {
+ $search_content_matches = \&Bugzilla::Search::_content_matches;
+}
+
+sub search_operator_field_override {
+ my ($self, $args) = @_;
+ my $search = $args->{'search'};
+ my $operators = $args->{'operators'};
+
+ my $cgi = Bugzilla->cgi;
+ my @comments = $cgi->param('comments');
+ my $exclude_comments = scalar(@comments) && !grep { $_ eq '1' } @comments;
+
+ if ($cgi->param('query_format') eq 'specific' && $exclude_comments) {
+ # use the non-comment operator
+ $operators->{'content'}->{matches} = \&_short_desc_matches;
+ $operators->{'content'}->{notmatches} = \&_short_desc_matches;
+
+ } else {
+ # restore default content operator
+ $operators->{'content'}->{matches} = $search_content_matches;
+ $operators->{'content'}->{notmatches} = $search_content_matches;
+ }
+}
+
+sub _short_desc_matches {
+ # copy of Bugzilla::Search::_content_matches
+
+ my $self = shift;
+ my %func_args = @_;
+ my ($chartid, $supptables, $term, $groupby, $fields, $t, $v) =
+ @func_args{qw(chartid supptables term groupby fields t v)};
+ my $dbh = Bugzilla->dbh;
+
+ # Add the fulltext table to the query so we can search on it.
+ my $table = "bugs_fulltext_$$chartid";
+ push(@$supptables, "LEFT JOIN bugs_fulltext AS $table " .
+ "ON bugs.bug_id = $table.bug_id");
+
+ # Create search terms to add to the SELECT and WHERE clauses.
+ my ($term1, $rterm1) = $dbh->sql_fulltext_search("$table.short_desc", $$v, 1);
+ $rterm1 = $term1 if !$rterm1;
+
+ # The term to use in the WHERE clause.
+ $$term = $term1;
+ if ($$t =~ /not/i) {
+ $$term = "NOT($$term)";
+ }
+
+ my $current = Bugzilla::Search::COLUMNS->{'relevance'}->{name};
+ $current = $current ? "$current + " : '';
+ # For NOT searches, we just add 0 to the relevance.
+ my $select_term = $$t =~ /not/ ? 0 : "($current$rterm1)";
+ Bugzilla::Search::COLUMNS->{'relevance'}->{name} = $select_term;
+}
+
__PACKAGE__->NAME;
diff --git a/extensions/BMO/lib/Data.pm b/extensions/BMO/lib/Data.pm
index 17b84a37e..ccc729a6d 100644
--- a/extensions/BMO/lib/Data.pm
+++ b/extensions/BMO/lib/Data.pm
@@ -27,7 +27,7 @@ use base qw(Exporter);
use Tie::IxHash;
our @EXPORT_OK = qw($cf_visible_in_products
- $cf_flags
+ $cf_flags $cf_disabled_flags
%group_to_cc_map
$blocking_trusted_setters
$blocking_trusted_requesters
@@ -78,7 +78,6 @@ tie(%$cf_visible_in_products, "Tie::IxHash",
"Add-on SDK" => [],
"addons.mozilla.org" => [],
"AUS" => [],
- "Camino" => [],
"Core Graveyard" => [],
"Core" => [],
"Directory" => [],
@@ -108,6 +107,9 @@ tie(%$cf_visible_in_products, "Tie::IxHash",
"Server Operations: Security",
],
},
+ qw/^cf_office$/ => {
+ "mozilla.org" => ["Server Operations: Desktop Issues"],
+ },
qr/^cf_crash_signature$/ => {
"addons.mozilla.org" => [],
"Add-on SDK" => [],
@@ -136,6 +138,9 @@ tie(%$cf_visible_in_products, "Tie::IxHash",
"Mozilla Labs" => [],
"mozilla.org" => [],
"Tech Evangelism" => [],
+ },
+ qw/^cf_due_date$/ => {
+ "Mozilla Reps" => [],
},
);
@@ -144,6 +149,28 @@ our $cf_flags = [
qr/^cf_(?:blocking|tracking|status)_/,
];
+# List of disabled fields.
+# Temp kludge until custom fields can be disabled correctly upstream.
+# Disabled fields are hidden unless they have a value set
+our $cf_disabled_flags = [
+ 'cf_blocking_20',
+ 'cf_status_20',
+ 'cf_tracking_firefox5',
+ 'cf_status_firefox5',
+ 'cf_blocking_thunderbird32',
+ 'cf_status_thunderbird32',
+ 'cf_blocking_thunderbird30',
+ 'cf_status_thunderbird30',
+ 'cf_blocking_seamonkey21',
+ 'cf_status_seamonkey21',
+ 'cf_tracking_seamonkey22',
+ 'cf_status_seamonkey22',
+ 'cf_tracking_firefox6',
+ 'cf_status_firefox6',
+ 'cf_tracking_thunderbird6',
+ 'cf_status_thunderbird6',
+];
+
# Who to CC on particular bugmails when certain groups are added or removed.
our %group_to_cc_map = (
'bugzilla-security' => 'security@bugzilla.org',
diff --git a/extensions/BMO/lib/FakeBug.pm b/extensions/BMO/lib/FakeBug.pm
index d8cebe379..5610f5433 100644
--- a/extensions/BMO/lib/FakeBug.pm
+++ b/extensions/BMO/lib/FakeBug.pm
@@ -1,7 +1,5 @@
package Bugzilla::Extension::BMO::FakeBug;
-use strict;
-
# hack to allow the bug entry templates to use check_can_change_field to see if
# various field values should be available to the current user
diff --git a/extensions/BMO/lib/Reports.pm b/extensions/BMO/lib/Reports.pm
index d1f979beb..f291e72e7 100644
--- a/extensions/BMO/lib/Reports.pm
+++ b/extensions/BMO/lib/Reports.pm
@@ -31,7 +31,8 @@ use DateTime;
use base qw(Exporter);
our @EXPORT_OK = qw(user_activity_report
- triage_reports);
+ triage_reports
+ group_admins);
sub user_activity_report {
my ($vars) = @_;
@@ -303,14 +304,16 @@ sub triage_reports {
# load product and components from input
- my $product = Bugzilla::Product->new({ name => $input->{'product'} });
+ my $product = Bugzilla::Product->new({ name => $input->{'product'} })
+ || ThrowUserError('invalid_object', { object => 'Product', value => $input->{'product'} });
my @component_ids;
if ($input->{'component'} ne '') {
my $ra_components = ref($input->{'component'})
? $input->{'component'} : [ $input->{'component'} ];
foreach my $component_name (@$ra_components) {
- my $component = Bugzilla::Component->new({ name => $component_name, product => $product });
+ my $component = Bugzilla::Component->new({ name => $component_name, product => $product })
+ || ThrowUserError('invalid_object', { object => 'Component', value => $component_name });
push @component_ids, $component->id;
}
}
@@ -319,15 +322,22 @@ sub triage_reports {
my $filter_commenter = $input->{'filter_commenter'};
my $filter_commenter_on = $input->{'commenter'};
+ my $filter_last = $input->{'filter_last'};
+ my $filter_last_period = $input->{'last'};
+
+ if (!$filter_commenter || $filter_last) {
+ $filter_commenter = '1';
+ $filter_commenter_on = 'reporter';
+ }
+
my $filter_commenter_id;
if ($filter_commenter && $filter_commenter_on eq 'is') {
Bugzilla::User::match_field({ 'commenter_is' => {'type' => 'single'} });
- my $user = Bugzilla::User->new({ name => $input->{'commenter_is'} });
+ my $user = Bugzilla::User->new({ name => $input->{'commenter_is'} })
+ || ThrowUserError('invalid_object', { object => 'User', value => $input->{'commenter_is'} });
$filter_commenter_id = $user ? $user->id : 0;
}
- my $filter_last = $input->{'filter_last'};
- my $filter_last_period = $input->{'last'};
my $filter_last_time;
if ($filter_last) {
if ($filter_last_period eq 'is') {
@@ -338,11 +348,10 @@ sub triage_reports {
$filter_last_period = 14 if $filter_last_period < 14;
}
}
- my $now = (time);
- $filter_commenter = 1 unless $filter_commenter || $filter_last;
# form sql queries
+ my $now = (time);
my $bugs_sql = "
SELECT bug_id, short_desc, reporter, creation_ts
FROM bugs
@@ -473,4 +482,41 @@ sub triage_reports {
$vars->{'input'} = $input;
}
+sub group_admins {
+ my ($vars, $filter) = @_;
+ my $dbh = Bugzilla->dbh;
+ my $user = Bugzilla->user;
+
+ $user->in_group('editusers')
+ || ThrowUserError('auth_failure', { group => 'editusers',
+ action => 'run',
+ object => 'group_admins' });
+
+ my $query = "
+ SELECT groups.name, " .
+ $dbh->sql_group_concat('profiles.login_name', "','", 1) . "
+ FROM groups
+ LEFT JOIN user_group_map
+ ON user_group_map.group_id = groups.id
+ AND user_group_map.isbless = 1
+ AND user_group_map.grant_type = 0
+ LEFT JOIN profiles
+ ON user_group_map.user_id = profiles.userid
+ WHERE groups.isbuggroup = 1
+ GROUP BY groups.name";
+
+ my @groups;
+ foreach my $group (@{ $dbh->selectall_arrayref($query) }) {
+ my @admins;
+ if ($group->[1]) {
+ foreach my $admin (split(/,/, $group->[1])) {
+ push(@admins, Bugzilla::User->new({ name => $admin }));
+ }
+ }
+ push(@groups, { name => $group->[0], admins => \@admins });
+ }
+
+ $vars->{'groups'} = \@groups;
+}
+
1;
diff --git a/extensions/BMO/template/en/default/account/create.html.tmpl b/extensions/BMO/template/en/default/account/create.html.tmpl
index 275df01f8..47355cf00 100644
--- a/extensions/BMO/template/en/default/account/create.html.tmpl
+++ b/extensions/BMO/template/en/default/account/create.html.tmpl
@@ -122,17 +122,17 @@ function onSubmit() {
<ol>
<li>
Please consider reading our
- <a href="https://developer.mozilla.org/en/Bug_writing_guidelines" target="_blank">[% terms.bug %] writing guidelines</a>.
+ <a href="https://developer.mozilla.org/en/Bug_writing_guidelines" target="_blank">bug writing guidelines</a>.
</li>
<li>
- [% terms.Bugzilla %] is a public place, so what you type and your email address will be visible
+ Bugzilla is a public place, so what you type and your email address will be visible
to all logged-in users. Some people use an
<a href="http://email.about.com/od/freeemailreviews/tp/free_email.htm" target="_blank">alternative email address</a>
for this reason.
</li>
<li>
Please give us an email address you want to use. Once we confirm that it works,
- you'll be asked to set a password and then you can start filing [% terms.bugs %] and helping fix them.
+ you'll be asked to set a password and then you can start filing bugs and helping fix them.
</li>
</ol>
</div>
@@ -158,9 +158,9 @@ function onSubmit() {
</table>
<p id="bmo-admin">
- If you think there's something wrong with [% terms.Bugzilla %], you can
+ If you think there's something wrong with Bugzilla, you can
<a href="mailto:bugzilla-admin@mozilla.org">send an email to the admins</a>, but
- remember, they can't file [% terms.bugs %] for you, or solve tech support problems.
+ remember, they can't file bugs for you, or solve tech support problems.
</p>
[% PROCESS global/footer.html.tmpl %]
diff --git a/extensions/BMO/template/en/default/bug/create/create-brownbag.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-brownbag.html.tmpl
index 72d520dd4..e4c6cabfb 100644
--- a/extensions/BMO/template/en/default/bug/create/create-brownbag.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-brownbag.html.tmpl
@@ -80,17 +80,16 @@ function trySubmit() {
<form method="post" action="post_bug.cgi" id="brownbagRequestForm" enctype="multipart/form-data"
onSubmit="return trySubmit();">
- <input type="hidden" name="product" value="mozilla.org">
- <input type="hidden" name="component" value="Server Operations: Desktop Issues">
- <input type="hidden" name="rep_platform" value="All">
- <input type="hidden" name="op_sys" value="Other">
- <input type="hidden" name="priority" value="--">
- <input type="hidden" name="version" value="other">
- <input type="hidden" name="bug_severity" id="bug_severity" value="normal">
- <input type="hidden" name="comment" id="comment" value="">
- <input type="hidden" name="short_desc" id="short_desc" value="">
- <input type="hidden" name="groups" value="mozilla-corporation-confidential">
-
+ <input type="hidden" name="product" value="mozilla.org">
+ <input type="hidden" name="component" value="Server Operations: Desktop Issues">
+ <input type="hidden" name="rep_platform" value="All">
+ <input type="hidden" name="op_sys" value="Other">
+ <input type="hidden" name="priority" value="--">
+ <input type="hidden" name="version" value="other">
+ <input type="hidden" name="bug_severity" id="bug_severity" value="normal">
+ <input type="hidden" name="comment" id="comment" value="">
+ <input type="hidden" name="short_desc" id="short_desc" value="">
+ <input type="hidden" name="groups" value="mozilla-corporation-confidential">
<table>
<tr>
@@ -98,6 +97,7 @@ function trySubmit() {
<td>
<input type="text" name="presenter" id="presenter" value="" size="60" />
</td>
+
</tr>
<tr>
@@ -146,7 +146,7 @@ function trySubmit() {
<option value="AM" selected>AM</option>
<option value="PM">PM</option>
</select>
- </td>
+ </td>
</tr>
<tr>
@@ -171,14 +171,14 @@ function trySubmit() {
</tr>
<tr>
- <td align="right"><strong>Archive this?</strong></td>
- <td align="left"><input type="checkbox" name="archive" id="archive" value="yes"></td>
+<td align="right"><strong>Archive this?</strong></td>
+<td align="left"><input type="checkbox" name="archive" id="archive" value="yes"></td>
</tr>
<tr>
- <td align="right"><strong>Need IT to help run A/V?</strong></td>
- <td align="left"><input type="checkbox" name="ithelp" id="ithelp" value="yes" checked></td>
+<td align="right"><strong>Need IT to help run A/V?</strong></td>
+<td align="left"><input type="checkbox" name="ithelp" id="ithelp" value="yes" checked></td>
</tr>
<tr>
@@ -198,11 +198,12 @@ function trySubmit() {
<th><label for="description">Description</label>:</th>
<td>
<em>Please briefly describe the brownbag and any specific needs you might have.</em><br>
+
<textarea id="description" name="description" rows="10" cols="80"></textarea>
</td>
</tr>
-</table>
+ </table>
<br>
<input type="submit" id="commit" value="Submit Request">
diff --git a/extensions/BMO/template/en/default/bug/create/create-itrequest.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-itrequest.html.tmpl
index d2f30475d..08207fd8c 100644
--- a/extensions/BMO/template/en/default/bug/create/create-itrequest.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-itrequest.html.tmpl
@@ -32,7 +32,7 @@
[% USE Bugzilla %]
<p><strong>Please use this form for IT requests only!</strong></p>
-<p>If you have a [% terms.bug %] to file, go <a href="enter_bug.cgi">here</a>.</p>
+<p>If you have a bug to file, go <a href="enter_bug.cgi">here</a>.</p>
<form method="post" action="post_bug.cgi" id="itRequestForm" enctype="multipart/form-data">
<input type="hidden" name="product" value="mozilla.org">
@@ -75,12 +75,12 @@
<td>
<select id="bug_severity" name="bug_severity" onchange="setsevdesc(this)">
- <option value="blocker">All work stops until this is done</option>
- <option value="critical">As soon as possible (urgent)</option>
- <option value="major">Within 24 hours</option>
- <option value="normal">Within the next week</option>
- <option value="minor" selected="selected">No rush</option>
- <option value="trivial">Whenever you get around to it</option>
+ <option value="blocker">All work for IT stops until this is done</option>
+ <option value="critical">IT should work on it soon as possible (urgent)</option>
+ <option value="major">IT should get to it within 24 hours</option>
+ <option value="normal">IT should get to it within the next week</option>
+ <option value="minor" selected="selected">No rush, but hopefully IT can get to it soon</option>
+ <option value="trivial">Whenever IT can get around to it</option>
<option value="enhancement">This is just an idea, filing it so we don't forget</option>
</select>
</td>
@@ -96,13 +96,16 @@
<input type="radio" name="component" id="componentac" onclick="setcompdesc(this)" value="Server Operations: Account Requests">
<label for="componentac">Request an LDAP/E-mail/etc. account</label><br>
<input type="radio" name="component" id="componentmvd" onclick="setcompdesc(this)" value="Server Operations: Desktop Issues">
- <label for="componentmvd">Desktop/Laptop/Printer/Phone problem/order/request</label><br>
- <input type="radio" name="component" id="componenttbm" onclick="setcompdesc(this)" value="Server Operations: Tinderbox Maintenance">
+ <label for="componentmvd">Desktop/Laptop/Printer/Phone/Tablet/License problem/order/request</label><br>
+ <input type="radio" name="component" id="componenttbm" onclick="setcompdesc(this)" value="Server Operations: RelEng">
<label for="componenttbm">Report a problem with a tinderbox machine</label><br>
- <input type="radio" name="component" id="componentwcp" onclick="setcompdesc(this)" value="Server Operations: Web Content Push">
- <label for="componentwcp">Deploy a change to a production website</label><br>
+ <input type="radio" name="component" id="componentwcp" onclick="setcompdesc(this)" value="Server Operations: Web Operations">
+ <label for="componentwcp">Report a problem with a Mozilla website, or to request a change or push</label><br>
+ <input type="radio" name="component" id="componentacl" onclick="setcompdesc(this)" value="Server Operations: ACL Request">
+ <label for="componentacl">Request a firewall change</label><br>
<input type="radio" name="component" id="componentso" onclick="setcompdesc(this)" value="Server Operations">
<label for="componentso">Any other issue</label><br>
+ Mailing list requests should be filed <a href="[% ulrbase FILTER none %]enter_bug.cgi?product=mozilla.org&format=mozlist">here</a> instead.
</td>
<td id="compdescription" align="left" style="color: green; padding-left: 1em">
</td>
@@ -169,7 +172,7 @@
</table>
<br>
- <!-- infra [% terms.bugs %] -->
+ <!-- infra bugs -->
<input type="checkbox" name="groups" id="groups" value="infra" checked="checked"><label for="groups"><strong>This is an internal issue which should not be publicly visible.</strong></label><br>(please uncheck this box if it isn't)
<br><br>
diff --git a/extensions/BMO/template/en/default/bug/create/create-mktgevent.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-mktgevent.html.tmpl
index 92354eac3..d6b6c188f 100644
--- a/extensions/BMO/template/en/default/bug/create/create-mktgevent.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-mktgevent.html.tmpl
@@ -91,18 +91,19 @@ function validateAndSubmit() {
<form method="post" action="post_bug.cgi" id="swagRequestForm" enctype="multipart/form-data"
onSubmit="return validateAndSubmit();">
- <input type="hidden" name="format" value="mktgevent">
- <input type="hidden" name="product" value="Marketing">
- <input type="hidden" name="component" value="Event Requests">
- <input type="hidden" name="rep_platform" value="All">
- <input type="hidden" name="op_sys" value="Other">
- <input type="hidden" name="priority" value="--">
- <input type="hidden" name="version" value="unspecified">
- <input type="hidden" name="bug_severity" id="bug_severity" value="normal">
- <input type="hidden" name="short_desc" id="short_desc" value="">
- <input type="hidden" name="groups" value="mozilla-corporation-confidential">
-
+ <input type="hidden" name="format" value="mktgevent">
+ <input type="hidden" name="product" value="Marketing">
+ <input type="hidden" name="component" value="Event Requests">
+ <input type="hidden" name="rep_platform" value="All">
+ <input type="hidden" name="op_sys" value="Other">
+ <input type="hidden" name="priority" value="--">
+ <input type="hidden" name="version" value="unspecified">
+ <input type="hidden" name="bug_severity" id="bug_severity" value="normal">
+
+ <input type="hidden" name="short_desc" id="short_desc" value="">
+ <input type="hidden" name="groups" value="mozilla-corporation-confidential">
<table>
+
<tr>
<td align="right"><strong>First Name: <span style="color: red;">*</span></strong></td>
<td align="left">
diff --git a/extensions/BMO/template/en/default/bug/create/create-mozlist.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-mozlist.html.tmpl
index 0a2edb5ee..138f1754b 100644
--- a/extensions/BMO/template/en/default/bug/create/create-mozlist.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-mozlist.html.tmpl
@@ -88,21 +88,21 @@
var listName = document.getElementById('listName').value;
var listAdmin = document.getElementById('listAdmin').value;
var listTypeRadio = document.getElementsByName('listType');
- var listType = "";
+ var listType = "";
- for (var i = 0; i < listTypeRadio.length; i++) {
- if (listTypeRadio[i].checked) {
- listType = listTypeRadio[i].value;
- }
- }
+ for (var i = 0; i < listTypeRadio.length; i++) {
+ if (listTypeRadio[i].checked) {
+ listType = listTypeRadio[i].value;
+ }
+ }
var alert_text = "";
var short_desc = "";
- if (listType) {
+ if (listType) {
if (listType == "lists.mozilla.org") {
document.getElementById('component').value = "Discussion Forums";
- short_desc = "Discussion Forum: " + listName;
+ short_desc = "Discussion Forum: " + listName;
} else if (listType == "mozilla.com" ) {
document.getElementById('component').value = "Server Operations: Desktop Issues";
short_desc = "[Zimbra Distribution List Request] " + listName + "@" + listType;
@@ -112,7 +112,7 @@
}
} else {
alert_text += "Please select a list type\n";
- }
+ }
if (!isFilledOut('listName')) {
alert_text += "Please enter the list name\n";
@@ -127,7 +127,7 @@
return false;
}
- document.getElementById('short_desc').value = short_desc;
+ document.getElementById('short_desc').value = short_desc;
return true;
}
@@ -220,8 +220,8 @@
<br>
<b>Note:</b>The list administrator is also initially considered to be the list moderator
and will be responsible for moderation tasks unless delegated to someone else. For
- convenience, [% terms.Bugzilla %] user accounts will autocomplete. The administrator is not required
- to have a [% terms.Bugzilla %] account, and you can enter an address that doesn't autocomplete if
+ convenience, Bugzilla user accounts will autocomplete. The administrator is not required
+ to have a Bugzilla account, and you can enter an address that doesn't autocomplete if
necessary.<hr />
</td>
</tr>
@@ -287,7 +287,7 @@
<br>
<div id="groups" style="display:none;">
- <!-- infra [% terms.bugs %] -->
+ <!-- infra bugs -->
<input type="checkbox" name="groups" id="group_35" value="infra" disabled="true">
<label for="group_35"><strong>This is an internal issue which should not be publicly visible.</strong></label>
<br><br>
diff --git a/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl
index 5b4cbf999..28a37a31e 100644
--- a/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl
@@ -57,12 +57,10 @@ var flags = new Array([% product.components.size %]);
comp_desc[[% count %]] = "[% c.description FILTER html_light FILTER js %]";
initialowners[[% count %]] = "[% c.default_assignee.login FILTER js %]";
[% flag_list = [] %]
- [% FOREACH f = c.flag_types.bug %]
- [% NEXT UNLESS f.is_active %]
+ [% FOREACH f = c.flag_types(is_active=>1).bug %]
[% flag_list.push(f.id) %]
[% END %]
- [% FOREACH f = c.flag_types.attachment %]
- [% NEXT UNLESS f.is_active %]
+ [% FOREACH f = c.flag_types(is_active=>1).attachment %]
[% flag_list.push(f.id) %]
[% END %]
flags[[% count %]] = [[% flag_list.join(",") FILTER js %]];
@@ -301,9 +299,9 @@ TUI_hide_default('expert_fields');
</td>
</tr>
</table>
- <input type="hidden" name="bug_severity" value="[% default.bug_severity FILTER html %]">
- <input type="hidden" name="rep_platform" value="[% default.rep_platform FILTER html %]">
- <input type="hidden" name="op_sys" value="[% default.op_sys FILTER html %]">
+ <input type="hidden" name="bug_severity" value="[% default.bug_severity %]">
+ <input type="hidden" name="rep_platform" value="[% default.rep_platform %]">
+ <input type="hidden" name="op_sys" value="[% default.op_sys %]">
<input type="hidden" name="version" value="unspecified">
</td>
</tr>
@@ -335,18 +333,17 @@ TUI_hide_default('expert_fields');
%]
<td rowspan="[% num_rows FILTER html %]">
- [% IF product.flag_types.bug.size > 0 %]
+ [% IF product.flag_types(is_active=>1).bug.size > 0 %]
[% display_flag_headers = 0 %]
[% any_flags_requesteeble = 0 %]
- [% FOREACH flag_type = product.flag_types.bug %]
- [% NEXT UNLESS flag_type.is_active %]
+ [% FOREACH flag_type = product.flag_types(is_active=>1).bug %]
[% display_flag_headers = 1 %]
[% SET any_flags_requesteeble = 1 IF flag_type.is_requestable && flag_type.is_requesteeble %]
[% END %]
[% IF display_flag_headers %]
- [% PROCESS "flag/list.html.tmpl" flag_types = product.flag_types.bug
+ [% PROCESS "flag/list.html.tmpl" flag_types = product.flag_types(is_active=>1).bug
any_flags_requesteeble = any_flags_requesteeble
flag_table_id = "bug_flags"
%]
@@ -469,7 +466,7 @@ TUI_hide_default('expert_fields');
<td colspan="3">
[% defaultcontent = BLOCK %]
[% IF cloned_bug_id %]
-+++ This [% terms.bug %] was initially created as a clone of [% terms.Bug %] #[% cloned_bug_id FILTER html %] +++
++++ This [% terms.bug %] was initially created as a clone of [% terms.Bug %] #[% cloned_bug_id %] +++
[% END %]
@@ -526,7 +523,7 @@ TUI_hide_default('expert_fields');
<legend>Add an attachment</legend>
<table class="attachment_entry">
[% PROCESS attachment/createformcontents.html.tmpl
- flag_types = product.flag_types.attachment
+ flag_types = product.flag_types(is_active=>1).attachment
any_flags_requesteeble = 1
flag_table_id ="attachment_flags" %]
</table>
@@ -555,7 +552,7 @@ TUI_hide_default('expert_fields');
<th>Status Whiteboard:</th>
<td colspan="3">
<input id="status_whiteboard" name="status_whiteboard" size="70"
- value="[% status_whiteboard FILTER html %]">
+ value="[% status_whiteboard %]">
</td>
</tr>
<tr>
@@ -592,10 +589,10 @@ TUI_hide_default('expert_fields');
<!-- Checkboxes -->
[% FOREACH g = group %]
&nbsp;&nbsp;&nbsp;&nbsp;
- <input type="checkbox" id="bit-[% g.bit FILTER html %]"
- name="bit-[% g.bit FILTER html %]" value="1"
+ <input type="checkbox" id="bit-[% g.bit %]"
+ name="bit-[% g.bit %]" value="1"
[% " checked=\"checked\"" IF g.checked %]>
- <label for="bit-[% g.bit FILTER html %]">[% g.description FILTER html_light %]</label><br>
+ <label for="bit-[% g.bit %]">[% g.description FILTER html_light %]</label><br>
[% END %]
</td>
</tr>
diff --git a/extensions/BMO/template/en/default/bug/create/create-presentation.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-presentation.html.tmpl
index 584b14912..cdbce5c8c 100644
--- a/extensions/BMO/template/en/default/bug/create/create-presentation.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-presentation.html.tmpl
@@ -86,7 +86,7 @@ function trySubmit() {
<input type="hidden" name="bug_severity" id="bug_severity" value="normal">
<input type="hidden" name="comment" id="comment" value="">
<input type="hidden" name="short_desc" id="short_desc" value="">
- <input type="hidden" name="groups" value="mozilla-corporation-confidential">
+ <input type="hidden" name="groups" value="mozilla-corporation-confidential">
<table>
<tr>
@@ -142,7 +142,7 @@ function trySubmit() {
<option value="AM" selected>AM</option>
<option value="PM">PM</option>
</select>
- </td>
+ </td>
</tr>
<tr>
diff --git a/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl
index b2698ae72..f7edccbe1 100644
--- a/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl
@@ -34,7 +34,7 @@
<p><strong>Swag Request:</strong> Please use this form to file a request for swag. </p>
<ol>
- <li>You first need submit a <a href="/enter_bug.cgi?product=Marketing&amp;format=mktgevent">Event Request Form</a>. You'll be asked for the [% terms.bug %] number below.</li>
+ <li>You first need submit a <a href="/enter_bug.cgi?product=Marketing&amp;format=mktgevent">Event Request Form</a>. You'll be asked for the bug number below.</li>
<li>Complete and submit request below.</li>
<li>Your request will be reviewed by the appropriate person in the Engagement team.</li>
<li>Your swag request will be reviewed and if approved shipped to you from
@@ -70,7 +70,7 @@ function validateAndSubmit() {
var alert_text = '';
if(!isFilledOut('firstname')) alert_text += "Please enter your first name\n";
if(!isFilledOut('lastname')) alert_text += "Please enter your last name\n";
- if(!isFilledOut('dependson')) alert_text += "Please enter the [% terms.bug %] number for your Event Request Form\n";
+ if(!isFilledOut('dependson')) alert_text += "Please enter the bug number for your Event Request Form\n";
if(!isValidEmail(document.getElementById('email').value)) alert_text += "Please enter a valid email address\n";
//Everything required is filled out..try to submit the form!
@@ -88,25 +88,25 @@ function validateAndSubmit() {
<form method="post" action="post_bug.cgi" id="swagRequestForm" enctype="multipart/form-data"
onSubmit="return validateAndSubmit();">
- <input type="hidden" name="format" value="swag">
- <input type="hidden" name="product" value="Marketing">
- <input type="hidden" name="component" value="Swag Requests">
- <input type="hidden" name="rep_platform" value="All">
- <input type="hidden" name="op_sys" value="Other">
- <input type="hidden" name="priority" value="--">
- <input type="hidden" name="version" value="unspecified">
- <input type="hidden" name="bug_severity" id="bug_severity" value="normal">
- <input type="hidden" name="short_desc" id="short_desc" value="">
- <input type="hidden" name="groups" value="mozilla-corporation-confidential">
-
+ <input type="hidden" name="format" value="swag">
+ <input type="hidden" name="product" value="Marketing">
+ <input type="hidden" name="component" value="Swag Requests">
+ <input type="hidden" name="rep_platform" value="All">
+ <input type="hidden" name="op_sys" value="Other">
+ <input type="hidden" name="priority" value="--">
+ <input type="hidden" name="version" value="unspecified">
+ <input type="hidden" name="bug_severity" id="bug_severity" value="normal">
+
+ <input type="hidden" name="short_desc" id="short_desc" value="">
+ <input type="hidden" name="groups" value="mozilla-corporation-confidential">
<table>
+
<tr>
<td align="right"><strong>First Name: <span style="color: red;">*</span></strong></td>
<td align="left">
<input type="text" name="firstname" id="firstname" value="" size="20" maxlength="20" />
</td>
</tr>
-
<tr>
<td align="right"><strong>Last Name: <span style="color: red;">*</span></strong></td>
<td align="left">
@@ -143,7 +143,7 @@ function validateAndSubmit() {
</tr>
<tr>
- <td align="right"><strong>[% terms.Bug %] number assigned to previously- &nbsp;&nbsp;<br>submitted <a href="/enter_bug.cgi?product=Marketing&amp;format=mktgevent">Event Request Form</a>: <span style="color: red;">*</span></strong></td>
+ <td align="right"><strong>Bug number assigned to previously- &nbsp;&nbsp;<br>submitted <a href="/enter_bug.cgi?product=Marketing&amp;format=mktgevent">Event Request Form</a>: <span style="color: red;">*</span></strong></td>
<td colspan="3"><input name="dependson" id="dependson"></td>
</tr>
diff --git a/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl b/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl
index 70a51b9ab..e7cea5d2b 100644
--- a/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl
@@ -62,9 +62,9 @@ the <a href="https://bugzilla.mozilla.org/enter_bug.cgi">full product list</a>.
<p>
<b>The product you have chosen is for [% terms.bug %] reports and enhancement requests for the
-<a href="http://www.bugzilla.org/">[% terms.Bugzilla %] [% terms.bug %] tracking software</a> only.</b>
-If your [% terms.bug %] is not reporting that [% terms.Bugzilla %] is broken or that you'd like
-a new feature in [% terms.Bugzilla %], your [% terms.bug %] report does not belong in this product.
+<a href="http://www.bugzilla.org/">Bugzilla [% terms.bug %] tracking software</a> only.</b>
+If your [% terms.bug %] is not reporting that Bugzilla is broken or that you'd like
+a new feature in Bugzilla, your [% terms.bug %] report does not belong in this product.
[% IF format == "guided" %]
See the instructions next to the stop sign above.
[% ELSE %]
@@ -72,22 +72,22 @@ a new feature in [% terms.Bugzilla %], your [% terms.bug %] report does not belo
[% END %]
</p>
-<p><b>We WILL NOT accept [% terms.bug %] reports for [% terms.Bugzilla %]
-installed via the Debian packaging system. If you obtained [% terms.Bugzilla %] from Debian,
+<p><b>We WILL NOT accept [% terms.bug %] reports for Bugzilla
+installed via the Debian packaging system. If you obtained Bugzilla from Debian,
please visit the <a href="http://www.debian.org/support">Debian Support page</a>,
-or file a [% terms.bug %] on the <a href="http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=bugzilla">Debian
-[% terms.Bug %] Tracker</a>.</b> The Debian package maintainer will then determine whether the [% terms.bug %]
-is specific to the package or not, and can move the [% terms.bug %] "upstream" if needed.</p>
+or file a bug on the <a href="http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=bugzilla">Debian
+Bug Tracker</a>.</b> The Debian package maintainer will then determine whether the bug
+is specific to the package or not, and can move the bug "upstream" if needed.</p>
<p>
-[% terms.Bugs %] specific to bugzilla.mozilla.org, rather than the [% terms.Bugzilla %] software in
+Bugs specific to bugzilla.mozilla.org, rather than the Bugzilla software in
general (which is used by many sites), should be filed in the
<a href="enter_bug.cgi?product=mozilla.org">mozilla.org product</a>.
</p>
<p>
Please do not file test [% terms.bugs %] or support requests here! You
-can test [% terms.Bugzilla %] at
+can test Bugzilla at
<a href="http://landfill.bugzilla.org/">landfill.bugzilla.org</a> and ask
for support in the
<a href="news://news.mozilla.org/mozilla.support.bugzilla">
@@ -106,7 +106,7 @@ support-bugzilla&#64;lists.mozilla.org mailing list</a>, or
[% UNLESS cloned_bug_id %]
Consider using the
<a href="enter_bug.cgi?product=[% product.name FILTER html %]&amp;format=guided">
-[% terms.Bugzilla %] Helper</a> instead of this form.
+Bugzilla Helper</a> instead of this form.
[% END +%]
Before reporting a [% terms.bug %], make sure you've read our
<a href="http://www.mozilla.org/quality/bug-writing-guidelines.html">
diff --git a/extensions/BMO/template/en/default/global/choose-product.html.tmpl b/extensions/BMO/template/en/default/global/choose-product.html.tmpl
index c957edca7..a65605a93 100644
--- a/extensions/BMO/template/en/default/global/choose-product.html.tmpl
+++ b/extensions/BMO/template/en/default/global/choose-product.html.tmpl
@@ -42,8 +42,7 @@
<center>
<hr>
-<p><span style="font-family: verdana,helvetica;">Looking for technical support or help getting your site to work with Mozilla? <a href="http://www.mozilla.org/support/">Visit the
-mozilla.org support page</a> before filing [% terms.bugs %].</span></p>
+<p><span style="font-family: verdana,helvetica;">Looking for technical support or help getting your site to work with Mozilla? <a href="http://www.mozilla.org/support/">Visit the mozilla.org support page</a> before filing bugs.</span></p>
<hr>
</center>
@@ -147,7 +146,7 @@ mozilla.org support page</a> before filing [% terms.bugs %].</span></p>
<br>
[% IF target == "enter_bug.cgi" AND user.settings.product_chooser.value != 'full_product_chooser' %]
-<p align="center">You can choose to get this screen by default when you click "New [% terms.Bug %]" by changing your <a href="userprefs.cgi?tab=settings">preferences</a>.</p>
+<p align="center">You can choose to get this screen by default when you click "New Bug" by changing your <a href="userprefs.cgi?tab=settings">preferences</a>.</p>
[% END %]
[% END %]
<br>
diff --git a/extensions/BMO/template/en/default/hook/bug/create/create-guided-form.html.tmpl b/extensions/BMO/template/en/default/hook/bug/create/create-guided-form.html.tmpl
index 5b58a9637..ee88aac7c 100644
--- a/extensions/BMO/template/en/default/hook/bug/create/create-guided-form.html.tmpl
+++ b/extensions/BMO/template/en/default/hook/bug/create/create-guided-form.html.tmpl
@@ -1,4 +1,4 @@
- <tr bgcolor="[% tablecolour FILTER html %]">
+ <tr bgcolor="[% tablecolour %]">
<td valign="middle" align="right">
<b>Security</b>
</td>
diff --git a/extensions/BMO/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl b/extensions/BMO/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl
index ba6eeb78c..0c68d8e72 100644
--- a/extensions/BMO/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl
+++ b/extensions/BMO/template/en/default/hook/bug/edit-after_custom_fields.html.tmpl
@@ -49,6 +49,7 @@
[% FOREACH field = Bugzilla.active_custom_fields %]
[% NEXT IF NOT user.id AND field.value == "---" %]
[% NEXT IF cf_hidden_in_product(field.name, bug.product, bug.component, 2) %]
+ [% NEXT IF cf_flag_disabled(field.name, bug) %]
[% custom_flags.push(field.name) %]
<tr id="row_[% field.name FILTER js %]">
<td>&nbsp;</td>
diff --git a/extensions/BMO/template/en/default/hook/global/header-additional_header.html.tmpl b/extensions/BMO/template/en/default/hook/global/header-additional_header.html.tmpl
index 05276d5f7..0277f3e7e 100644
--- a/extensions/BMO/template/en/default/hook/global/header-additional_header.html.tmpl
+++ b/extensions/BMO/template/en/default/hook/global/header-additional_header.html.tmpl
@@ -21,7 +21,7 @@
<link rel="shortcut icon" href="extensions/BMO/web/images/bugzilla.png">
[% IF bug %]
-<link id="shorturl" rev="canonical" href="https://bugzil.la/[% bug.bug_id FILTER uri %]">
+<link id="shorturl" rev="canonical" href="https://bugzil.la/[% bug.bug_id %]">
[% END %]
<style type="text/css">
diff --git a/extensions/BMO/template/en/default/hook/global/user-error-auth_failure_object.html.tmpl b/extensions/BMO/template/en/default/hook/global/user-error-auth_failure_object.html.tmpl
new file mode 100644
index 000000000..067347f3b
--- /dev/null
+++ b/extensions/BMO/template/en/default/hook/global/user-error-auth_failure_object.html.tmpl
@@ -0,0 +1,3 @@
+[% IF object == 'group_admins' %]
+ the group administrators report
+[% END %]
diff --git a/extensions/BMO/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/BMO/template/en/default/hook/global/user-error-errors.html.tmpl
index 5a3e2bed6..85881aca7 100644
--- a/extensions/BMO/template/en/default/hook/global/user-error-errors.html.tmpl
+++ b/extensions/BMO/template/en/default/hook/global/user-error-errors.html.tmpl
@@ -34,22 +34,7 @@
[% title = "Invalid Date" %]
The date '[% date FILTER html %]' is invalid.
-[% ELSIF error == "remo_payment_invalid_product" %]
- [% title = "Mozilla Reps Payment Invalid $terms.Bug" %]
- You can only attach budget payment information to [% terms.bugs %] under
- the product 'Mozilla Reps' and component 'Budget Requests'.
-
-[% ELSIF error == "remo_payment_bug_edit_denied" %]
- [% title = "Mozilla Reps Payment $terms.Bug Edit Denied" %]
- You do not have permission to edit [% terms.bug %] '[% bug_id FILTER html %]'.
-
-[% ELSIF error == "remo_payment_cancel_dupe" %]
- [% title = "Already filed payment request" %]
- You already used the form to file
- <a href="[% urlbase FILTER html %]attachment.cgi?id=[% attachid FILTER uri %]&action=edit">
- attachment [% attachid FILTER uri %]</a>.<br>
- <br>
- You can either <a href="[% urlbase FILTER html %]page.cgi?id=remo-form-payment.html">
- create a new payment request</a> or [% "go back to $terms.bug $bugid" FILTER bug_link(bugid) FILTER none %].
+[% ELSIF error == "invalid_object" %]
+ Invalid [% object FILTER html %]: "[% value FILTER html %]"
[% END %]
diff --git a/extensions/BMO/template/en/default/hook/global/user-error.html.tmpl/auth_failure/permissions.html.tmpl b/extensions/BMO/template/en/default/hook/global/user-error.html.tmpl/auth_failure/permissions.html.tmpl
index 346e02373..5f6ca946a 100644
--- a/extensions/BMO/template/en/default/hook/global/user-error.html.tmpl/auth_failure/permissions.html.tmpl
+++ b/extensions/BMO/template/en/default/hook/global/user-error.html.tmpl/auth_failure/permissions.html.tmpl
@@ -22,7 +22,7 @@
[% IF (group == "canconfirm" OR group == "editbugs") AND !reason %]
<p>
- If you are attempting to confirm an unconfirmed [% terms.bug %] or edit the fields of a [% terms.bug %],
+ If you are attempting to confirm an unconfirmed bug or edit the fields of a bug,
<a href="http://www.gerv.net/hacking/before-you-mail-gerv.html#bugzilla-permissions">find
out how to get the necessary permissions</a>.
</p>
diff --git a/extensions/BMO/template/en/default/hook/pages/fields-resolution.html.tmpl b/extensions/BMO/template/en/default/hook/pages/fields-resolution.html.tmpl
new file mode 100644
index 000000000..4d12ab345
--- /dev/null
+++ b/extensions/BMO/template/en/default/hook/pages/fields-resolution.html.tmpl
@@ -0,0 +1,13 @@
+<dt>
+ [% display_value("resolution", "INCOMPLETE") FILTER html %]
+</dt>
+<dd>
+ The problem is vaguely described with no steps to reproduce,
+ or is a support request. The reporter should be directed to the
+ product's support page for help diagnosing the issue. If there
+ are only a few comments in the [% terms.bug %], it may be reopened only if
+ the original reporter provides more info, or confirms someone
+ else's steps to reproduce. If the [% terms.bug %] is long, when enough info
+ is provided a new [% terms.bug %] should be filed and the original [% terms.bug %]
+ marked as a duplicate of it.
+</dd>
diff --git a/extensions/BMO/template/en/default/hook/reports/menu-end.html.tmpl b/extensions/BMO/template/en/default/hook/reports/menu-end.html.tmpl
index b42ff8d2a..6e8463020 100644
--- a/extensions/BMO/template/en/default/hook/reports/menu-end.html.tmpl
+++ b/extensions/BMO/template/en/default/hook/reports/menu-end.html.tmpl
@@ -31,5 +31,11 @@
%]page.cgi?id=triage_reports.html">Triage Report</a></strong> - Report
on UNCONFIRMED [% terms.bugs %] to assist triage.
</li>
+ [% IF user.in_group('editusers') %]
+ <li>
+ <strong><a href="[% urlbase FILTER none
+ %]page.cgi?id=group_admins.html">Group Admins</a></strong> - Group Admins Report
+ </li>
+ [% END %]
</ul>
diff --git a/extensions/BMO/template/en/default/list/list.microsummary.tmpl b/extensions/BMO/template/en/default/list/list.microsummary.tmpl
index a095a7e4d..8f6b13cbd 100644
--- a/extensions/BMO/template/en/default/list/list.microsummary.tmpl
+++ b/extensions/BMO/template/en/default/list/list.microsummary.tmpl
@@ -21,8 +21,9 @@
[% PROCESS global/variables.none.tmpl %]
+
[% IF searchname %]
- [% searchname FILTER html %] ([% bugs.size %])
+ [% searchname %] ([% bugs.size %])
[% ELSE %]
[% terms.Bug %] List ([% bugs.size %])
[% END %]
diff --git a/extensions/BMO/template/en/default/list/server-push.html.tmpl b/extensions/BMO/template/en/default/list/server-push.html.tmpl
index 1c1f3cf36..40432a35b 100644
--- a/extensions/BMO/template/en/default/list/server-push.html.tmpl
+++ b/extensions/BMO/template/en/default/list/server-push.html.tmpl
@@ -34,7 +34,7 @@
<div style="margin-top: 15%; text-align: center;">
<center><img src="extensions/BMO/web/images/mozchomp.gif" alt=""
width="160" height="87"></center>
- <h1>Please wait while your [% terms.bugs %] are retrieved.</h1>
+ <h1>Please wait while your bugs are retrieved.</h1>
</div>
[% IF debug %]
diff --git a/extensions/BMO/template/en/default/pages/etiquette.html.tmpl b/extensions/BMO/template/en/default/pages/etiquette.html.tmpl
index 8bccaea9d..281057eeb 100644
--- a/extensions/BMO/template/en/default/pages/etiquette.html.tmpl
+++ b/extensions/BMO/template/en/default/pages/etiquette.html.tmpl
@@ -21,15 +21,15 @@
#%]
[% INCLUDE global/header.html.tmpl
- title = "$terms.Bugzilla Etiquette"
+ title = "Bugzilla Etiquette"
style = "li { margin: 5px } .heading { font-weight: bold }" %]
<p>
There's a number of <i lang="fr">faux pas</i> you can commit when using
- [% terms.Bugzilla %]. At the very
+ Bugzilla. At the very
least, these will make Mozilla contributors upset at you; if committed enough
times they will cause those contributors to demand the disabling of your
- [% terms.Bugzilla %] account. So, ignore this advice at your peril.
+ Bugzilla account. So, ignore this advice at your peril.
</p>
<p>
@@ -47,14 +47,14 @@
<li>
<span class="heading">No pointless comments</span>.
Unless you have something constructive and helpful to say, do not add a
- comment to a [% terms.bug %]. In [% terms.bugs %] where there is a heated debate going on, you
+ comment to a bug. In bugs where there is a heated debate going on, you
should be even more
inclined not to add a comment. Unless you have something new to contribute,
- then the [% terms.bug %] owner is aware of all the issues, and will make a judgement
- as to what to do. If you agree the [% terms.bug %] should be fixed, vote for it.
+ then the bug owner is aware of all the issues, and will make a judgement
+ as to what to do. If you agree the bug should be fixed, vote for it.
Additional "I see this too" or "It works for me" comments are unnecessary
unless they are on a different platform or a significantly different build.
- Constructive and helpful thoughts unrelated to the topic of the [% terms.bug %]
+ Constructive and helpful thoughts unrelated to the topic of the bug
should go in the appropriate
<a href="http://www.mozilla.org/about/forums/">newsgroup</a>.
</li>
@@ -63,8 +63,8 @@
<span class="heading">No obligation</span>.
"Open Source" is not the same as "the developers must do my bidding."
Everyone here wants to help, but the only person who has any
- <i>obligation</i> to fix the [% terms.bugs %] you want fixed is you. Therefore, you
- should not act as if you expect someone to fix a [% terms.bug %] by a particular date
+ <i>obligation</i> to fix the bugs you want fixed is you. Therefore, you
+ should not act as if you expect someone to fix a bug by a particular date
or release. Aggressive or repeated demands will not be received
well and will almost certainly diminish the impact and interest in your
suggestions.
@@ -80,17 +80,17 @@
<i>things</i>, not <i>people</i>. Examples of things include: interfaces,
algorithms, and schedules. Examples of people include: developers,
designers and users. <b>Attacking a person may result in you being banned
- from [% terms.Bugzilla %].</b>
+ from Bugzilla.</b>
</li>
<li>
<span class="heading">No private email</span>.
- Unless the [% terms.bug %] owner or another respected project contributor has asked you
+ Unless the bug owner or another respected project contributor has asked you
to email them with specific information, please place all information
- relating to [% terms.bugs %]
- in the [% terms.bug %] itself. Do not send them by private email; no-one else can read
+ relating to bugs
+ in the bug itself. Do not send them by private email; no-one else can read
them if you do that, and they'll probably just get ignored. If a file
- is too big for [% terms.Bugzilla %], add a comment giving the file size and contents
+ is too big for Bugzilla, add a comment giving the file size and contents
and ask what to do.
</li>
</ol>
@@ -99,19 +99,19 @@
<ol>
<li>
- <span class="heading">No messing with other people's [% terms.bugs %]</span>.
- Unless you are the [% terms.bug %] assignee, or have some say over the use of their
+ <span class="heading">No messing with other people's bugs</span>.
+ Unless you are the bug assignee, or have some say over the use of their
time, never change the Priority or Target Milestone fields. If in doubt,
- do not change the fields of [% terms.bugs %] you do not own - add a comment
+ do not change the fields of bugs you do not own - add a comment
instead, suggesting the change.
</li>
<li>
<span class="heading">No whining about decisions</span>.
- If a respected project contributor has marked a [% terms.bug %] as INVALID, then it is
+ If a respected project contributor has marked a bug as INVALID, then it is
invalid. Someone filing another duplicate of it does not change this. Unless
you have further important evidence, do not post a comment arguing that an
- INVALID or WONTFIX [% terms.bug %] should be reopened.
+ INVALID or WONTFIX bug should be reopened.
</li>
</ol>
@@ -129,7 +129,7 @@
<p>
If you see someone not following these rules, the first step is, as an exception
to guideline 1.4, to make them aware of this document by <em>private</em> mail.
- Flaming people publically in [% terms.bugs %] violates guidelines 1.1 and 1.3. In the case of
+ Flaming people publically in bugs violates guidelines 1.1 and 1.3. In the case of
persistent offending you should report the matter to
<a href="mailto:gerv@mozilla.org">Gerv</a>.
</p>
@@ -141,7 +141,7 @@
<p>
Other useful documents:
- <a href="page.cgi?id=bug-writing.html">The [% terms.Bug %] Writing Guidelines</a>.
+ <a href="page.cgi?id=bug-writing.html">The Bug Writing Guidelines</a>.
</p>
[% INCLUDE global/footer.html.tmpl %]
diff --git a/extensions/BMO/template/en/default/pages/group_admins.html.tmpl b/extensions/BMO/template/en/default/pages/group_admins.html.tmpl
new file mode 100644
index 000000000..a55b6e2ad
--- /dev/null
+++ b/extensions/BMO/template/en/default/pages/group_admins.html.tmpl
@@ -0,0 +1,53 @@
+[%# The contents of this file are subject to the Mozilla Public
+ # License Version 1.1 (the "License"); you may not use this file
+ # except in compliance with the License. You may obtain a copy of
+ # the License at http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS
+ # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # rights and limitations under the License.
+ #
+ # The Original Code is the BMO Extension
+ #
+ # The Initial Developer of the Original Code is the Mozilla Foundation
+ # Portions created by the Initial Developers are Copyright (C) 2011 the
+ # Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s):
+ # David Lawrence <dkl@mozilla.com>
+ #%]
+
+[% INCLUDE global/header.html.tmpl
+ title = "Group Admins Report"
+ style_urls = [ "extensions/BMO/web/styles/reports.css" ]
+%]
+
+[% IF groups.size > 0 %]
+ <table border="0" cellspacing="0" id="report" width="100%">
+ <tr id="report-header">
+ <th align="left">Name</th>
+ <th align="left">Admins</th>
+ </tr>
+
+ [% FOREACH group = groups %]
+ [% count = loop.count() %]
+ <tr class="report_item [% count % 2 == 1 ? "report_row_odd" : "report_row_even" %]">
+ <td>
+ [% group.name FILTER html %]
+ </td>
+ <td>
+ [% FOREACH admin = group.admins %]
+ [% INCLUDE global/user.html.tmpl who = admin %][% ", " UNLESS loop.last %]
+ [% END %]
+ </td>
+ </tr>
+ [% END %]
+ </table>
+[% ELSE %]
+ <p>
+ No groups found.
+ </p>
+[% END %]
+
+[% INCLUDE global/footer.html.tmpl %]
diff --git a/extensions/BMO/template/en/default/pages/triage_reports.html.tmpl b/extensions/BMO/template/en/default/pages/triage_reports.html.tmpl
index a7f26e86d..023dc4791 100644
--- a/extensions/BMO/template/en/default/pages/triage_reports.html.tmpl
+++ b/extensions/BMO/template/en/default/pages/triage_reports.html.tmpl
@@ -59,7 +59,7 @@ var selected_components = [
<input type="hidden" name="id" value="triage_reports.html">
<input type="hidden" name="action" value="run">
-Show UNCONFIRMED [% terms.bugs %] with:
+Show UNCONFIRMED bugs with:
<table id="triage_form">
<tr>
@@ -149,7 +149,7 @@ Show UNCONFIRMED [% terms.bugs %] with:
</p>
<table border="0" cellspacing="0" id="report" width="100%">
<tr id="report-header">
- <th>[% terms.Bug %] / Date</th>
+ <th>Bug / Date</th>
<th>Summary</th>
<th>Reporter / Commenter</th>
<th>Comment Date</th>
@@ -190,7 +190,7 @@ Show UNCONFIRMED [% terms.bugs %] with:
[% ELSE %]
<p>
- No [% terms.bugs %] found.
+ No bugs found.
</p>
[% END %]
diff --git a/extensions/BMO/template/en/default/pages/user_activity.html.tmpl b/extensions/BMO/template/en/default/pages/user_activity.html.tmpl
index 904f0ba62..dd16595ab 100644
--- a/extensions/BMO/template/en/default/pages/user_activity.html.tmpl
+++ b/extensions/BMO/template/en/default/pages/user_activity.html.tmpl
@@ -96,7 +96,7 @@
[% IF incomplete_data %]
<p>
- There used to be an issue in <a href="http://www.bugzilla.org/">[% terms.Bugzilla %]</a>
+ There used to be an issue in <a href="http://www.bugzilla.org/">Bugzilla</a>
which caused activity data to be lost if there were a large number of cc's
or dependencies. That has been fixed, but some data was already lost in
your activity table that could not be regenerated. The changes that
@@ -110,7 +110,7 @@
<tr id="report-header">
<th>Who</th>
<th>When</th>
- <th>[% terms.Bug %]</th>
+ <th>Bug</th>
<th>What</th>
<th>Removed</th>
<th>Added</th>
@@ -131,9 +131,9 @@
[% "</tr><tr>" IF loop.index > 0 %]
<td>
[% IF change.attachid %]
- <a href="attachment.cgi?id=[% change.attachid FILTER uri %]">Attachment #[% change.attachid FILTER html %]</a>
+ <a href="attachment.cgi?id=[% change.attachid %]">Attachment #[% change.attachid %]</a>
[% ELSIF change.comment.defined && change.fieldname == 'longdesc' %]
- [% "Comment $change.comment.count" FILTER bug_link(operation.bug, comment_num => change.comment.count) FILTER none %]
+ [% "Comment $change.comment.count" FILTER bug_link(operation.bug, comment_num => change.comment.count) %]
[% ELSE %]
[%+ field_descs.${change.fieldname} FILTER html %]
[% END %]
diff --git a/extensions/BMO/web/js/edit_bug.js b/extensions/BMO/web/js/edit_bug.js
index 6f0bc4587..5fc2ab6f7 100644
--- a/extensions/BMO/web/js/edit_bug.js
+++ b/extensions/BMO/web/js/edit_bug.js
@@ -54,3 +54,18 @@ function bmo_show_tracking_flags() {
}
}
}
+
+// -- make attachment table, comments, new comment textarea equal widths
+
+YAHOO.util.Event.onDOMReady(function() {
+ var comment_tables = Dom.getElementsByClassName('bz_comment_table', 'table', 'comments');
+ if (comment_tables.length) {
+ var comment_width = comment_tables[0].getElementsByTagName('td')[0].clientWidth + 'px';
+ var attachment_table = Dom.get('attachment_table');
+ if (attachment_table)
+ attachment_table.style.width = comment_width;
+ var new_comment = Dom.get('comment');
+ if (new_comment)
+ new_comment.style.width = comment_width;
+ }
+});
diff --git a/extensions/BMO/web/js/edituser_menu.js b/extensions/BMO/web/js/edituser_menu.js
new file mode 100644
index 000000000..9ce78d9ce
--- /dev/null
+++ b/extensions/BMO/web/js/edituser_menu.js
@@ -0,0 +1,26 @@
+var admin_usermenu;
+
+YAHOO.util.Event.onDOMReady(function() {
+ admin_usermenu = new YAHOO.widget.Menu('admin_usermenu', { position : 'dynamic' });
+ admin_usermenu.addItems([
+ { text: 'Edit', url: '#', target: '_new' },
+ { text: 'Activity', url: '#', target: '_new' },
+ { text: 'Mail', url: '#', target: '_new' }
+ ]);
+ admin_usermenu.render(document.body);
+});
+
+function show_admin_username(event, id, email) {
+ if (!admin_usermenu)
+ return;
+ admin_usermenu.getItem(0).cfg.setProperty('url', 'editusers.cgi?action=edit&userid=' + id);
+ admin_usermenu.getItem(1).cfg.setProperty('url',
+ 'page.cgi?id=user_activity.html&action=run' +
+ '&from=' + YAHOO.util.Date.format(new Date(new Date() - (1000 * 60 * 60 * 24 * 14)), {format: '%Y-%m-%d'}) +
+ '&to=' + YAHOO.util.Date.format(new Date(), {format: '%Y-%m-%d'}) +
+ '&who=' + escape(email));
+ admin_usermenu.getItem(2).cfg.setProperty('url', 'mailto:' + escape(email));
+ admin_usermenu.cfg.setProperty('xy', YAHOO.util.Event.getXY(event));
+ admin_usermenu.show();
+}
+
diff --git a/extensions/BMO/web/styles/reports.css b/extensions/BMO/web/styles/reports.css
new file mode 100644
index 000000000..3106a6295
--- /dev/null
+++ b/extensions/BMO/web/styles/reports.css
@@ -0,0 +1,37 @@
+.hidden {
+ display: none;
+}
+
+#triage_form th {
+ text-align: left;
+}
+
+#product, #component {
+ width: 20em;
+}
+
+#report tr.bugitem:hover {
+ background: #ccccff;
+}
+
+#report td {
+ padding: 1px 10px 1px 10px;
+}
+
+#report-header {
+ background: #dddddd;
+}
+
+.report_row_odd {
+ background-color: #F7F7F7;
+ color: #000000;
+}
+
+.report_row_even {
+ background-color: #FFFFFF;
+ color: #000000;
+}
+
+tr.report_item:hover {
+ background-color: #ccccff;
+}
diff --git a/extensions/BzAPI/template/en/default/config.json.tmpl b/extensions/BzAPI/template/en/default/config.json.tmpl
index f83dee5fb..d567c6c55 100644
--- a/extensions/BzAPI/template/en/default/config.json.tmpl
+++ b/extensions/BzAPI/template/en/default/config.json.tmpl
@@ -127,7 +127,7 @@ OLDATTACH2NEW = {
[% FOREACH cl IN classifications %]
[% cl_name_for.${cl.id} = cl.name %]
"[% cl.name FILTER json %]": {
- "id": [% cl.id FILTER json %],
+ "id": [% cl.id %],
"description": "[% cl.description FILTER json %]",
"products": [
[% FOREACH product IN cl.products %]
@@ -142,7 +142,7 @@ OLDATTACH2NEW = {
"product": {
[% FOREACH product = products %]
"[% product.name FILTER json %]": {
- "id": [% product.id FILTER json %],
+ "id": [% product.id %],
"description": "[% product.description FILTER json %]",
"is_active": [% product.isactive ? "true" : "false" %],
"is_permitting_unconfirmed": [% product.allows_unconfirmed ? "true" : "false" %],
@@ -152,16 +152,15 @@ OLDATTACH2NEW = {
"component": {
[% FOREACH component = product.components %]
"[% component.name FILTER json %]": {
- "id": [% component.id FILTER json %],
+ "id": [% component.id %],
[% IF show_flags %]
"flag_type": [
[% flag_types =
- component.flag_types.bug.merge(component.flag_types.attachment) %]
+ component.flag_types(is_active=>1).bug.merge(component.flag_types(is_active=>1).attachment) %]
[%-# "first" flag used to get commas right; can't use loop.last() in case
# last flag is inactive %]
[% first = 1 %]
[% FOREACH flag_type = flag_types %]
- [% NEXT UNLESS flag_type.is_active %]
[% all_visible_flag_types.${flag_type.id} = flag_type %]
[% ',' UNLESS first %][% flag_type.id FILTER json %][% first = 0 %]
[% END %]],
@@ -187,7 +186,7 @@ OLDATTACH2NEW = {
"group": [
[% FOREACH group = product.groups_valid %]
- [% group.id FILTER json %][% ',' UNLESS loop.last() %]
+ [% group.id %][% ',' UNLESS loop.last() %]
[% END %]
]
}[% ',' UNLESS loop.last() %]
@@ -196,7 +195,7 @@ OLDATTACH2NEW = {
"group": {
[% FOREACH group = product.groups_valid %]
- "[% group.id FILTER json %]": {
+ "[% group.id %]": {
"name": "[% group.name FILTER json %]",
"description": "[% group.description FILTER json %]",
"is_accepting_bugs": [% group.is_bug_group ? 'true' : 'false' %],
@@ -208,15 +207,15 @@ OLDATTACH2NEW = {
[% IF show_flags %]
"flag_type": {
[% FOREACH flag_type = all_visible_flag_types.values.sort('name') %]
- "[%+ flag_type.id FILTER json %]": {
+ "[%+ flag_type.id %]": {
"name": "[% flag_type.name FILTER json %]",
"description": "[% flag_type.description FILTER json %]",
[% IF user.in_group("editcomponents") %]
[% IF flag_type.request_group_id %]
- "request_group": [% flag_type.request_group_id FILTER json %],
+ "request_group": [% flag_type.request_group_id %],
[% END %]
[% IF flag_type.grant_group_id %]
- "grant_group": [% flag_type.grant_group_id FILTER json %],
+ "grant_group": [% flag_type.grant_group_id %],
[% END %]
[% END %]
"is_for_bugs": [% flag_type.target_type == "bug" ? 'true' : 'false' %],
@@ -310,7 +309,7 @@ OLDATTACH2NEW = {
[% IF newname.match("^cf_") %]
"is_on_bug_entry": [% item.enter_bug ? 'true' : 'false' %],
[% END %]
- "type": [% item.type || type_id_for.$newname || 0 FILTER json %]
+ "type": [% item.type || type_id_for.$newname || 0 %]
}[% ',' UNLESS loop.last() %]
[% END %]
}
diff --git a/extensions/ComponentWatching/template/en/default/account/prefs/component_watch.html.tmpl b/extensions/ComponentWatching/template/en/default/account/prefs/component_watch.html.tmpl
index c3247078a..057a32e36 100644
--- a/extensions/ComponentWatching/template/en/default/account/prefs/component_watch.html.tmpl
+++ b/extensions/ComponentWatching/template/en/default/account/prefs/component_watch.html.tmpl
@@ -113,19 +113,19 @@ You are currently watching:
[% FOREACH watch IN watches %]
<tr>
[% IF (watch.component) %]
- <td><input type="checkbox" name="del_[% watch.product.id FILTER uri %]_[% watch.component.id FILTER uri %]" value="1"></td>
+ <td><input type="checkbox" name="del_[% watch.product.id %]_[% watch.component.id %]" value="1"></td>
<td>[% watch.component.product.name FILTER html %]</td>
<td>
- <a href="buglist.cgi?product=[% watch.product.name FILTER uri -%]
- &component=[% watch.component.name FILTER uri %]&resolution=---">
+ <a href="buglist.cgi?product=[% watch.product.name FILTER url ~%]
+ &component=[% watch.component.name FILTER url %]&resolution=---">
[% watch.component.name FILTER html %]
</a>
</td>
[% ELSE %]
- <td><input type="checkbox" name="del_[% watch.product.id FILTER uri %]" value="1"></td>
+ <td><input type="checkbox" name="del_[% watch.product.id %]" value="1"></td>
<td>[% watch.product.name FILTER html %]</td>
<td>
- <a href="describecomponents.cgi?product=[% watch.product.name FILTER uri %]">
+ <a href="describecomponents.cgi?product=[% watch.product.name FILTER url %]">
__Any__
</a>
</td>
diff --git a/extensions/Example/Extension.pm b/extensions/Example/Extension.pm
index 4498d2b22..ef20a28f0 100644
--- a/extensions/Example/Extension.pm
+++ b/extensions/Example/Extension.pm
@@ -211,12 +211,15 @@ sub search_operator_field_override {
sub _component_nonchanged {
my $original = shift;
- my ($invocant, $args) = @_;
+ my $invocant = shift;
+
+ my %func_args = @_;
+ $invocant->$original(%func_args);
- $invocant->$original($args);
# Actually, it does not change anything in the result,
# just an example.
- $args->{term} = $args->{term} . " OR 1=2";
+ my ($term) = @func_args{qw(term)};
+ $$term = $$term . " OR 1=2";
}
sub bugmail_recipients {
@@ -261,14 +264,9 @@ sub config_modify_panels {
my $auth_params = $panels->{'auth'}->{params};
my ($info_class) = grep($_->{name} eq 'user_info_class', @$auth_params);
my ($verify_class) = grep($_->{name} eq 'user_verify_class', @$auth_params);
-
+
push(@{ $info_class->{choices} }, 'CGI,Example');
push(@{ $verify_class->{choices} }, 'Example');
-
- push(@$auth_params, { name => 'param_example',
- type => 't',
- default => 0,
- checker => \&check_numeric });
}
sub db_schema_abstract_schema {
@@ -456,26 +454,6 @@ sub install_update_db {
# $dbh->bz_add_index('example', 'example_new_column_idx', [qw(value)]);
}
-sub install_update_db_fielddefs {
- my $dbh = Bugzilla->dbh;
-# $dbh->bz_add_column('fielddefs', 'example_column',
-# {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => ''});
-}
-
-sub job_map {
- my ($self, $args) = @_;
-
- my $job_map = $args->{job_map};
-
- # This adds the named class (an instance of TheSchwartz::Worker) as a
- # handler for when a job is added with the name "some_task".
- $job_map->{'some_task'} = 'Bugzilla::Extension::Example::Job::SomeClass';
-
- # Schedule a job like this:
- # my $queue = Bugzilla->job_queue();
- # $queue->insert('some_task', { some_parameter => $some_variable });
-}
-
sub mailer_before_send {
my ($self, $args) = @_;
diff --git a/extensions/Example/lib/Config.pm b/extensions/Example/lib/Config.pm
index 75db22957..a126e82df 100644
--- a/extensions/Example/lib/Config.pm
+++ b/extensions/Example/lib/Config.pm
@@ -25,8 +25,6 @@ use warnings;
use Bugzilla::Config::Common;
-our $sortkey = 5000;
-
sub get_param_list {
my ($class) = @_;
diff --git a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
index 403b63a6e..8f8817344 100644
--- a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
+++ b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
@@ -27,7 +27,7 @@
[% PROCESS global/variables.none.tmpl %]
[% PROCESS global/header.html.tmpl
- title = "Enter A $terms.Bug"
+ title = "Enter A Bug"
javascript_urls = [
'extensions/GuidedBugEntry/web/js/products.js',
'extensions/GuidedBugEntry/web/js/guided.js',
@@ -41,8 +41,8 @@
<input id="yui-history-field" type="hidden">
<noscript>
-You require JavaScript to use this [% terms.bug %] entry form.<br><br>
-Please use the <a href="enter_bug.cgi?format=__default__">advanced [% terms.bug %] entry form</a>.
+You require JavaScript to use this bug entry form.<br><br>
+Please use the <a href="enter_bug.cgi?format=__default__">advanced bug entry form</a>.
</noscript>
<div id="loading" class="hidden">
@@ -62,7 +62,7 @@ YAHOO.util.Dom.removeClass('loading', 'hidden');
<div id="advanced">
<a id="advanced_img" href="enter_bug.cgi?format=__default__"><img
src="extensions/GuidedBugEntry/web/images/advanced.png" width="16" height="16" border="0"></a>
- <a id="advanced_link" href="enter_bug.cgi?format=__default__">Switch to the advanced [% terms.bug %] entry form</a>
+ <a id="advanced_link" href="enter_bug.cgi?format=__default__">Switch to the advanced bug entry form</a>
</div>
<script type="text/javascript">
@@ -94,7 +94,7 @@ dupes.setLabels(
[% BLOCK page_title %]
<div id="page_title">
- <h2>Enter A [% terms.Bug %]</h2>
+ <h2>Enter A Bug</h2>
<h3>Step [% step_number FILTER html %] of 3</h3>
</div>
[% END %]
@@ -145,7 +145,7 @@ dupes.setLabels(
<td class="product_img">
<a href="javascript:void(0)"
[% IF onclick %]
- onclick="[% onclick FILTER none %]"
+ onclick="[% onclick %]"
[% ELSE %]
onclick="product.select('[% name FILTER js %]')"
[% END %]
@@ -156,7 +156,7 @@ dupes.setLabels(
<h2>
<a href="javascript:void(0)"
[% IF onclick %]
- onclick="[% onclick FILTER none %]"
+ onclick="[% onclick %]"
[% ELSE %]
onclick="product.select('[% name FILTER js %]')"
[% END %]
@@ -260,14 +260,14 @@ dupes.setLabels(
</div>
</td>
<td width="100%">
- &bullet; <a href="http://input.mozilla.org/feedback/">Provide other feedback about Firefox</a><br>
- &bullet; <a href="http://input.mozilla.org/feedback/#sad">Report an issue with a web site that I use</a><br>
- &bullet; <a href="enter_bug.cgi?format=guided&product=Core">Report an issue with Firefox on a site that I've developed</a><br>
+ &bull; <a href="http://input.mozilla.org/feedback/">Provide other feedback about Firefox</a><br>
+ &bull; <a href="http://input.mozilla.org/feedback/#sad">Report an issue with a web site that I use</a><br>
+ &bull; <a href="enter_bug.cgi?format=guided&product=Core">Report an issue with Firefox on a site that I've developed</a><br>
</td>
</tr>
</table>
<h3>
- None of the above; my [% terms.bug %] is in:
+ None of the above; my bug is in:
</h3>
[% END %]
@@ -275,14 +275,14 @@ dupes.setLabels(
<tr>
<td>
<div class="exit_img">
- <a href="[% href FILTER none %]"
+ <a href="[% href %]"
><img src="extensions/GuidedBugEntry/web/images/[% icon FILTER uri %]" width="32" height="32"
></a>
</div>
</td>
<td width="100%">
<h2>
- <a href="[% href FILTER none %]">[% name FILTER html %]</a>
+ <a href="[% href %]">[% name FILTER html %]</a>
</h2>
[% desc FILTER html %]
</td>
@@ -359,7 +359,7 @@ Product: <b><span id="dupes_product_name">?</span></b>:
<li>Please fill out this form clearly, precisely and in as much detail as you can manage.</li>
<li>Please report only a single problem at a time.</li>
<li><a href="https://developer.mozilla.org/en/Bug_writing_guidelines" target="_blank">These guidelines</a>
-explain how to write effective [% terms.bug %] reports.</li>
+explain how to write effective bug reports.</li>
</ul>
<table id="bugForm" cellspacing="0">
@@ -512,7 +512,7 @@ explain how to write effective [% terms.bug %] reports.</li>
<tr class="odd">
<td>&nbsp;</td>
<td colspan="2" id="submitTD">
- <input type="submit" id="submit" value="Submit [% terms.Bug %]">
+ <input type="submit" id="submit" value="Submit Bug">
</td>
</tr>
diff --git a/extensions/GuidedBugEntry/web/js/guided.js b/extensions/GuidedBugEntry/web/js/guided.js
index f600dbb21..e3efd6446 100644
--- a/extensions/GuidedBugEntry/web/js/guided.js
+++ b/extensions/GuidedBugEntry/web/js/guided.js
@@ -162,8 +162,7 @@ var product = {
// show support message
if (products[productName] && products[productName].support) {
- Dom.get("product_support_message").innerHTML =
- YAHOO.lang.escapeHTML(products[productName].support);
+ Dom.get("product_support_message").innerHTML = products[productName].support;
Dom.removeClass("product_support", "hidden");
} else {
Dom.addClass("product_support", "hidden");
@@ -251,6 +250,7 @@ var dupes = {
this._elList = Dom.get('dupes_list');
Event.onBlur(this._elSummary, this._onSummaryBlur);
+ Event.addListener(this._elSummary, 'input', this._onSummaryBlur);
Event.addListener(this._elSummary, 'keydown', this._onSummaryKeyDown);
Event.addListener(this._elSummary, 'keyup', this._onSummaryKeyUp);
Event.addListener(this._elSearch, 'click', this._doSearch);
diff --git a/extensions/GuidedBugEntry/web/style/guided.css b/extensions/GuidedBugEntry/web/style/guided.css
index f4d8ec90d..b0c766d11 100644
--- a/extensions/GuidedBugEntry/web/style/guided.css
+++ b/extensions/GuidedBugEntry/web/style/guided.css
@@ -81,6 +81,8 @@
.exits {
width: 600px;
margin-bottom: 10px;
+ border: 1px solid #aaa;
+ border-radius: 5px;
}
.exits td {
diff --git a/extensions/InlineHistory/Config.pm b/extensions/InlineHistory/Config.pm
new file mode 100644
index 000000000..dd4002856
--- /dev/null
+++ b/extensions/InlineHistory/Config.pm
@@ -0,0 +1,31 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+# the specific language governing rights and limitations under the License.
+#
+# The Original Code is the InlineHistory Bugzilla Extension;
+# Derived from the Bugzilla Tweaks Addon.
+#
+# The Initial Developer of the Original Code is the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2011 the Initial
+# Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Johnathan Nightingale <johnath@mozilla.com>
+# Ehsan Akhgari <ehsan@mozilla.com>
+# Byron Jones <glob@mozilla.com>
+#
+# ***** END LICENSE BLOCK *****
+
+package Bugzilla::Extension::InlineHistory;
+use strict;
+
+use constant NAME => 'InlineHistory';
+
+__PACKAGE__->NAME;
diff --git a/extensions/InlineHistory/Extension.pm b/extensions/InlineHistory/Extension.pm
new file mode 100644
index 000000000..63a67304b
--- /dev/null
+++ b/extensions/InlineHistory/Extension.pm
@@ -0,0 +1,183 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+# the specific language governing rights and limitations under the License.
+#
+# The Original Code is the InlineHistory Bugzilla Extension;
+# Derived from the Bugzilla Tweaks Addon.
+#
+# The Initial Developer of the Original Code is the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2011 the Initial
+# Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Johnathan Nightingale <johnath@mozilla.com>
+# Ehsan Akhgari <ehsan@mozilla.com>
+# Byron Jones <glob@mozilla.com>
+#
+# ***** END LICENSE BLOCK *****
+
+package Bugzilla::Extension::InlineHistory;
+use strict;
+use base qw(Bugzilla::Extension);
+
+use Bugzilla::User::Setting;
+use Bugzilla::Constants;
+use Bugzilla::Attachment;
+
+our $VERSION = '1.4';
+
+sub template_before_process {
+ my ($self, $args) = @_;
+ my $file = $args->{'file'};
+ my $vars = $args->{'vars'};
+ my $user = Bugzilla->user;
+ my $dbh = Bugzilla->dbh;
+
+ return unless $user && $user->id && $user->settings;
+ return unless $user->settings->{'inline_history'}->{'value'} eq 'on';
+
+ # in the header we just need to set the var, to ensure the css and
+ # javascript get included
+ if ($file eq 'bug/show-header.html.tmpl') {
+ $vars->{'ih_activity'} = 1;
+ return;
+ } elsif ($file ne 'bug/edit.html.tmpl') {
+ return;
+ }
+
+ # note: bug/edit.html.tmpl doesn't support multiple bugs
+ my $bug_id = exists $vars->{'bugs'}
+ ? $vars->{'bugs'}[0]->id
+ : $vars->{'bug'}->id;
+
+ # build bug activity
+ my ($activity) = Bugzilla::Bug::GetBugActivity($bug_id);
+ $activity = _add_duplicates($bug_id, $activity);
+
+ # augment and tweak
+ foreach my $operation (@$activity) {
+ # make operation.who an object
+ $operation->{who} = Bugzilla::User->new({ name => $operation->{who} });
+ for (my $i = 0; $i < scalar(@{$operation->{changes}}); $i++) {
+ my $change = $operation->{changes}->[$i];
+
+ # make an attachment object
+ if ($change->{attachid}) {
+ $change->{attach} = Bugzilla::Attachment->new($change->{attachid});
+ }
+
+ # empty resolutions are displayed as --- by default
+ # make it explicit here to enable correct display of the change
+ if ($change->{fieldname} eq 'resolution') {
+ $change->{removed} = '---' if $change->{removed} eq '';
+ $change->{added} = '---' if $change->{added} eq '';
+ }
+
+ # make boolean fields true/false instead of 1/0
+ my ($table, $field) = ('bugs', $change->{fieldname});
+ if ($field =~ /^([^\.]+)\.(.+)$/) {
+ ($table, $field) = ($1, $2);
+ }
+ my $column = $dbh->bz_column_info($table, $field);
+ if ($column && $column->{TYPE} eq 'BOOLEAN') {
+ $change->{removed} = '';
+ $change->{added} = $change->{added} ? 'true' : 'false';
+ }
+
+ # split multiple flag changes (must be processed last)
+ if ($change->{fieldname} eq 'flagtypes.name') {
+ my @added = split(/, /, $change->{added});
+ my @removed = split(/, /, $change->{removed});
+ next if scalar(@added) <= 1 && scalar(@removed) <= 1;
+ # remove current change
+ splice(@{$operation->{changes}}, $i, 1);
+ # restructure into added/removed for each flag
+ my %flags;
+ foreach my $added (@added) {
+ my ($value, $name) = $added =~ /^((.+).)$/;
+ $flags{$name}{added} = $value;
+ $flags{$name}{removed} |= '';
+ }
+ foreach my $removed (@removed) {
+ my ($value, $name) = $removed =~ /^((.+).)$/;
+ $flags{$name}{added} |= '';
+ $flags{$name}{removed} = $value;
+ }
+ # clone current change, modify and insert
+ foreach my $flag (sort keys %flags) {
+ my $flag_change = {};
+ foreach my $key (keys %$change) {
+ $flag_change->{$key} = $change->{$key};
+ }
+ $flag_change->{removed} = $flags{$flag}{removed};
+ $flag_change->{added} = $flags{$flag}{added};
+ splice(@{$operation->{changes}}, $i, 0, $flag_change);
+ }
+ $i--;
+ }
+ }
+ }
+
+ $vars->{'ih_activity'} = $activity;
+}
+
+sub _add_duplicates {
+ # insert 'is a dupe of this bug' comment to allow js to display
+ # as activity
+
+ my ($bug_id, $activity) = @_;
+
+ my $dbh = Bugzilla->dbh;
+ my $sth = $dbh->prepare("
+ SELECT profiles.login_name, " .
+ $dbh->sql_date_format('bug_when', '%Y.%m.%d %H:%i:%s') . ",
+ extra_data,
+ thetext
+ FROM longdescs
+ INNER JOIN profiles ON profiles.userid = longdescs.who
+ WHERE bug_id = ?
+ AND (
+ type = ?
+ OR thetext LIKE '%has been marked as a duplicate of this%'
+ )
+ ORDER BY bug_when
+ ");
+ $sth->execute($bug_id, CMT_HAS_DUPE);
+
+ while (my($who, $when, $dupe_id, $the_text) = $sth->fetchrow_array) {
+ if (!$dupe_id) {
+ next unless $the_text =~ / (\d+) has been marked as a duplicate of this/;
+ $dupe_id = $1;
+ }
+ my $entry = {
+ 'when' => $when,
+ 'who' => $who,
+ 'changes' => [
+ {
+ 'removed' => '',
+ 'added' => $dupe_id,
+ 'attachid' => undef,
+ 'fieldname' => 'dupe',
+ 'dupe' => 1,
+ }
+ ],
+ };
+ push @$activity, $entry;
+ }
+
+ return [ sort { $a->{when} cmp $b->{when} } @$activity ];
+}
+
+sub install_before_final_checks {
+ my ($self, $args) = @_;
+ add_setting('inline_history', ['on', 'off'], 'off');
+}
+
+__PACKAGE__->NAME;
diff --git a/extensions/InlineHistory/README b/extensions/InlineHistory/README
new file mode 100644
index 000000000..f5aaf163f
--- /dev/null
+++ b/extensions/InlineHistory/README
@@ -0,0 +1,10 @@
+InlineHistory inserts bug activity inline with the comments when viewing a bug.
+It was derived from the Bugzilla Tweaks Addon by Ehasn Akhgari.
+
+For technical and performance reasons it is only available to logged in users,
+and is enabled by a User Preference.
+
+It works with an unmodified install of Bugzilla 4.0 and 4.2.
+
+If you have modified your show_bug template, the javascript in
+web/inline-history.js may need to be updated to suit your installation.
diff --git a/extensions/InlineHistory/template/en/default/hook/bug/comments-aftercomments.html.tmpl b/extensions/InlineHistory/template/en/default/hook/bug/comments-aftercomments.html.tmpl
new file mode 100644
index 000000000..4af08dca8
--- /dev/null
+++ b/extensions/InlineHistory/template/en/default/hook/bug/comments-aftercomments.html.tmpl
@@ -0,0 +1,135 @@
+[%# ***** BEGIN LICENSE BLOCK *****
+ # Version: MPL 1.1
+ #
+ # The contents of this file are subject to the Mozilla Public License Version
+ # 1.1 (the "License"); you may not use this file except in compliance with
+ # the License. You may obtain a copy of the License at
+ # http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS IS" basis,
+ # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ # for the specific language governing rights and limitations under the
+ # License.
+ #
+ # The Original Code is the InlineHistory Bugzilla Extension;
+ # Derived from the Bugzilla Tweaks Addon.
+ #
+ # The Initial Developer of the Original Code is the Mozilla Foundation.
+ # Portions created by the Initial Developer are Copyright (C) 2011 the
+ # Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s):
+ # Johnathan Nightingale <johnath@mozilla.com>
+ # Ehsan Akhgari <ehsan@mozilla.com>
+ # Byron Jones <glob@mozilla.com>
+ #
+ # ***** END LICENSE BLOCK *****
+ #%]
+
+[% IF ih_activity %]
+[%# this div exists to allow bugzilla-tweaks to detect when we're active %]
+<div id="inline-history-ext"></div>
+
+<script>
+ var ih_activity = new Array();
+ var ih_activity_flags = new Array();
+ var ih_activity_sort_order = '[% user.settings.comment_sort_order.value FILTER js %]';
+ [% FOREACH operation = ih_activity %]
+ var html = '';
+ [% has_cc = 0 %]
+ [% has_flag = 0 %]
+ [% FOREACH change = operation.changes %]
+ [%# track flag changes %]
+ [% IF change.fieldname == 'flagtypes.name' && change.added != '' %]
+ var item = new Array(5);
+ item[0] = '[% operation.who.login FILTER js %]';
+ item[1] = '[% operation.when FILTER time FILTER js %]';
+ item[2] = '[% change.attachid FILTER js %]';
+ item[3] = '[% change.added FILTER js %]';
+ item[4] = '[% operation.who.identity FILTER js %]';
+ ih_activity_flags.push(item);
+ [% has_flag = 1 %]
+ [% END %]
+
+ [%# wrap CC changes in a span for toggling visibility %]
+ [% IF change.fieldname == 'cc' %]
+ html += '<span class="ih_cc">';
+ [% has_cc = 1 %]
+ [% END %]
+
+ [%# make attachment changes better %]
+ [% IF change.attachid %]
+ html += '<a '
+ + 'href="attachment.cgi?action=edit&amp;id=[% change.attachid FILTER none %]" '
+ + 'title="[% change.attach.description FILTER js %]" '
+ + 'class="[% "bz_obsolete" IF change.attach.isobsolete %]"'
+ + '>Attachment #[% change.attachid FILTER none %]</a> - ';
+ [% END %]
+
+ [%# display duplicates as history rather than comments %]
+ [% IF change.dupe %]
+ html += 'Duplicate of this [% terms.bug %]: ';
+ [% ELSE %]
+ html += '[% field_descs.${change.fieldname} FILTER js %]: ';
+ [% END %]
+
+ [% IF change.removed != '' %]
+ [% IF change.added == '' %]
+ html += '<span class="ih_deleted">';
+ [% END %]
+ [% PROCESS add_change value = change.removed, is_old = 1 %]
+ [% IF change.added == '' %]
+ html += '</span>';
+ [% ELSE %]
+ html += ' &#x2794; ';
+ [% END %]
+ [% END %]
+ [% PROCESS add_change value = change.added, is_old = 0 %]
+ [% "html += '<br>';" UNLESS loop.last %]
+
+ [% IF change.fieldname == 'cc' %]
+ html += '</span>';
+ [% END %]
+ [% END %]
+ var item = new Array(7);
+ item[0] = '[% operation.who.login FILTER js %]';
+ item[1] = '[% operation.when FILTER time FILTER js %]';
+ item[2] = html;
+ item[3] = '<div class="bz_comment_head">'
+ + '<span class="bz_comment_user">'
+ + '[% INCLUDE global/user.html.tmpl who = operation.who FILTER js %]'
+ + '</span>'
+ + '<span class="bz_comment_time"> ' + item[1] + ' </span>'
+ + '</div>';
+ item[4] = [% IF has_cc && (operation.changes.size == 1) %]true[% ELSE %]false[% END %];
+ item[5] = [% IF change.dupe %][% change.added FILTER js %][% ELSE %]0[% END %];
+ item[6] = [% IF has_flag %]true[% ELSE %]false[% END %];
+ ih_activity[[% loop.index %]] = item;
+ [% END %]
+ inline_history.init();
+</script>
+[% END %]
+
+[% BLOCK add_change %]
+ html += '[%~%]
+ [% '<span class="old">' IF is_old %]
+ [% IF change.fieldname == 'estimated_time' ||
+ change.fieldname == 'remaining_time' ||
+ change.fieldname == 'work_time' %]
+ [% PROCESS formattimeunit time_unit = value FILTER html FILTER js %]
+ [% ELSIF change.fieldname == 'blocked' ||
+ change.fieldname == 'dependson' ||
+ change.fieldname == 'dupe' %]
+ [% value FILTER bug_list_link FILTER js %]
+ [% ELSIF change.fieldname == 'assigned_to' ||
+ change.fieldname == 'reporter' ||
+ change.fieldname == 'qa_contact' ||
+ change.fieldname == 'cc' ||
+ change.fieldname == 'flagtypes.name' %]
+ [% display_value(change.fieldname, value) FILTER email FILTER js %]
+ [% ELSE %]
+ [% display_value(change.fieldname, value) FILTER html FILTER js %]
+ [% END %]
+ [% '</span>' IF is_old %]
+ [%~ %]';
+[% END %]
diff --git a/extensions/InlineHistory/template/en/default/hook/bug/show-header-end.html.tmpl b/extensions/InlineHistory/template/en/default/hook/bug/show-header-end.html.tmpl
new file mode 100644
index 000000000..221175105
--- /dev/null
+++ b/extensions/InlineHistory/template/en/default/hook/bug/show-header-end.html.tmpl
@@ -0,0 +1,33 @@
+[%# ***** BEGIN LICENSE BLOCK *****
+ # Version: MPL 1.1
+ #
+ # The contents of this file are subject to the Mozilla Public License Version
+ # 1.1 (the "License"); you may not use this file except in compliance with
+ # the License. You may obtain a copy of the License at
+ # http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS IS" basis,
+ # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ # for the specific language governing rights and limitations under the
+ # License.
+ #
+ # The Original Code is the InlineHistory Bugzilla Extension;
+ # Derived from the Bugzilla Tweaks Addon.
+ #
+ # The Initial Developer of the Original Code is the Mozilla Foundation.
+ # Portions created by the Initial Developer are Copyright (C) 2011 the
+ # Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s):
+ # Johnathan Nightingale <johnath@mozilla.com>
+ # Ehsan Akhgari <ehsan@mozilla.com>
+ # Byron Jones <glob@mozilla.com>
+ #
+ # ***** END LICENSE BLOCK *****
+ #%]
+
+[% IF ih_activity %]
+ [% style_urls.push('extensions/InlineHistory/web/style.css') %]
+ [% javascript_urls.push('extensions/InlineHistory/web/inline-history.js') %]
+[% END %]
+
diff --git a/extensions/InlineHistory/template/en/default/hook/global/setting-descs-settings.none.tmpl b/extensions/InlineHistory/template/en/default/hook/global/setting-descs-settings.none.tmpl
new file mode 100644
index 000000000..852dac22f
--- /dev/null
+++ b/extensions/InlineHistory/template/en/default/hook/global/setting-descs-settings.none.tmpl
@@ -0,0 +1,31 @@
+[%# ***** BEGIN LICENSE BLOCK *****
+ # Version: MPL 1.1
+ #
+ # The contents of this file are subject to the Mozilla Public License Version
+ # 1.1 (the "License"); you may not use this file except in compliance with
+ # the License. You may obtain a copy of the License at
+ # http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS IS" basis,
+ # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ # for the specific language governing rights and limitations under the
+ # License.
+ #
+ # The Original Code is the InlineHistory Bugzilla Extension;
+ # Derived from the Bugzilla Tweaks Addon.
+ #
+ # The Initial Developer of the Original Code is the Mozilla Foundation.
+ # Portions created by the Initial Developer are Copyright (C) 2011 the
+ # Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s):
+ # Johnathan Nightingale <johnath@mozilla.com>
+ # Ehsan Akhgari <ehsan@mozilla.com>
+ # Byron Jones <glob@mozilla.com>
+ #
+ # ***** END LICENSE BLOCK *****
+ #%]
+
+[%
+ setting_descs.inline_history = "When viewing a $terms.bug, show all $terms.bug activity",
+%]
diff --git a/extensions/InlineHistory/web/inline-history.js b/extensions/InlineHistory/web/inline-history.js
new file mode 100644
index 000000000..9fb860e3c
--- /dev/null
+++ b/extensions/InlineHistory/web/inline-history.js
@@ -0,0 +1,396 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+ * the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is the InlineHistory Bugzilla Extension;
+ * Derived from the Bugzilla Tweaks Addon.
+ * Derived from the Bugzilla Tweaks Addon.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011 the Initial
+ * Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Johnathan Nightingale <johnath@mozilla.com>
+ * Ehsan Akhgari <ehsan@mozilla.com>
+ * Byron Jones <glob@mozilla.com>
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+var inline_history = {
+ _ccDivs: null,
+ _hasAttachmentFlags: false,
+ _hasBugFlags: false,
+
+ init: function() {
+ Dom = YAHOO.util.Dom;
+
+ // remove 'has been marked as a duplicate of this bug' comments
+ var reDuplicate = /\*\*\* \S+ \d+ has been marked as a duplicate of this/;
+ var reBugId = /show_bug\.cgi\?id=(\d+)/;
+ var comments = Dom.getElementsByClassName("bz_comment", 'div', 'comments');
+ for (var i = 1, il = comments.length; i < il; i++) {
+ var textDiv = Dom.getElementsByClassName('bz_comment_text', 'pre', comments[i]);
+ if (textDiv) {
+ var match = reDuplicate.exec(textDiv[0].textContent || textDiv[0].innerText);
+ if (match) {
+ // grab the comment and bug number from the element
+ var comment = comments[i];
+ var number = comment.id.substr(1);
+ var time = this.trim(Dom.getElementsByClassName('bz_comment_time', 'span', comment)[0].innerHTML);
+ var dupeId = 0;
+ match = reBugId.exec(Dom.get('comment_text_' + number).innerHTML);
+ if (match)
+ dupeId = match[1];
+ // remove the element
+ comment.parentNode.removeChild(comment);
+ // update the html for the history item to include the comment number
+ if (dupeId == 0)
+ continue;
+ for (var j = 0, jl = ih_activity.length; j < jl; j++) {
+ var item = ih_activity[j];
+ if (item[5] == dupeId && item[1] == time) {
+ // insert comment number and link into the header
+ item[3] = item[3].substr(0, item[3].length - 6) // remove trailing </div>
+ // add comment number
+ + '<span class="bz_comment_number" id="c' + number + '">'
+ + '<a href="#c' + number + '">Comment ' + number + '</a>'
+ + '</span>'
+ + '</div>';
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // ensure new items are placed immediately after the last comment
+ var commentDivs = Dom.getElementsByClassName('bz_comment', 'div', 'comments');
+ if (!commentDivs.length) return;
+ var lastCommentDiv = commentDivs[commentDivs.length - 1];
+
+ // insert activity into the correct location
+ var commentTimes = Dom.getElementsByClassName('bz_comment_time', 'span', 'comments');
+ for (var i = 0, il = ih_activity.length; i < il; i++) {
+ var item = ih_activity[i];
+ // item[0] : who
+ // item[1] : when
+ // item[2] : change html
+ // item[3] : header html
+ // item[4] : bool; cc-only
+ // item[5] : int; dupe bug id (or 0)
+ // item[6] : bool; is flag
+ var user = item[0];
+ var time = item[1];
+
+ var reachedEnd = false;
+ var start_index = ih_activity_sort_order == 'newest_to_oldest_desc_first' ? 1 : 0;
+ for (var j = start_index, jl = commentTimes.length; j < jl; j++) {
+ var commentHead = commentTimes[j].parentNode;
+ var mainUser = Dom.getElementsByClassName('email', 'a', commentHead)[0].href.substr(7);
+ var text = commentTimes[j].textContent || commentTimes[j].innerText;
+ var mainTime = this.trim(text);
+
+ if (ih_activity_sort_order == 'oldest_to_newest' ? time > mainTime : time < mainTime) {
+ if (j < commentTimes.length - 1) {
+ continue;
+ } else {
+ reachedEnd = true;
+ }
+ }
+
+ var inline = (mainUser == user && time == mainTime);
+ var currentDiv = document.createElement("div");
+
+ // place ih_cc class on parent container if it's the only child
+ var containerClass = '';
+ if (item[4]) {
+ item[2] = item[2].replace('"ih_cc"', '""');
+ containerClass = 'ih_cc';
+ }
+
+ if (inline) {
+ // assume that the change was made by the same user
+ commentHead.parentNode.appendChild(currentDiv);
+ currentDiv.innerHTML = item[2];
+ Dom.addClass(currentDiv, 'ih_inlinehistory');
+ Dom.addClass(currentDiv, containerClass);
+ if (item[6])
+ this.setFlagChangeID(item, commentHead.parentNode.id);
+
+ } else {
+ // the change was made by another user
+ if (!reachedEnd) {
+ var parentDiv = commentHead.parentNode;
+ var previous = this.previousElementSibling(parentDiv);
+ if (previous && previous.className.indexOf("ih_history") >= 0) {
+ currentDiv = this.previousElementSibling(parentDiv);
+ } else {
+ parentDiv.parentNode.insertBefore(currentDiv, parentDiv);
+ }
+ } else {
+ var parentDiv = commentHead.parentNode;
+ var next = this.nextElementSibling(parentDiv);
+ if (next && next.className.indexOf("ih_history") >= 0) {
+ currentDiv = this.nextElementSibling(parentDiv);
+ } else {
+ lastCommentDiv.parentNode.insertBefore(currentDiv, lastCommentDiv.nextSibling);
+ }
+ }
+
+ var itemHtml = '<div class="ih_history_item ' + containerClass + '" '
+ + 'id="h' + i + '">'
+ + item[3] + item[2]
+ + '</div>';
+
+ if (ih_activity_sort_order == 'oldest_to_newest') {
+ currentDiv.innerHTML = currentDiv.innerHTML + itemHtml;
+ } else {
+ currentDiv.innerHTML = itemHtml + currentDiv.innerHTML;
+ }
+ currentDiv.setAttribute("class", "bz_comment ih_history");
+ if (item[6])
+ this.setFlagChangeID(item, 'h' + i);
+ }
+ break;
+ }
+ }
+
+ // find comment blocks which only contain cc changes, shift the ih_cc
+ var historyDivs = Dom.getElementsByClassName('ih_history', 'div', 'comments');
+ for (var i = 0, il = historyDivs.length; i < il; i++) {
+ var historyDiv = historyDivs[i];
+ var itemDivs = Dom.getElementsByClassName('ih_history_item', 'div', historyDiv);
+ var ccOnly = true;
+ for (var j = 0, jl = itemDivs.length; j < jl; j++) {
+ if (!Dom.hasClass(itemDivs[j], 'ih_cc')) {
+ ccOnly = false;
+ break;
+ }
+ }
+ if (ccOnly) {
+ for (var j = 0, jl = itemDivs.length; j < jl; j++) {
+ Dom.removeClass(itemDivs[j], 'ih_cc');
+ }
+ Dom.addClass(historyDiv, 'ih_cc');
+ }
+ }
+
+ if (this._hasAttachmentFlags)
+ this.linkAttachmentFlags();
+ if (this._hasBugFlags)
+ this.linkBugFlags();
+
+ ih_activity = undefined;
+ ih_activity_flags = undefined;
+
+ this._ccDivs = Dom.getElementsByClassName('ih_cc', '', 'comments');
+ this.hideCC();
+ YAHOO.util.Event.onDOMReady(this.addCCtoggler);
+ },
+
+ setFlagChangeID: function(changeItem, id) {
+ // put the ID for the change into ih_activity_flags
+ for (var i = 0, il = ih_activity_flags.length; i < il; i++) {
+ var flagItem = ih_activity_flags[i];
+ // flagItem[0] : who.login
+ // flagItem[1] : when
+ // flagItem[2] : attach id
+ // flagItem[3] : flag
+ // flagItem[4] : who.identity
+ // flagItem[5] : change div id
+ if (flagItem[0] == changeItem[0] && flagItem[1] == changeItem[1]) {
+ // store the div
+ flagItem[5] = id;
+ // tag that we have flags to process
+ if (flagItem[2]) {
+ this._hasAttachmentFlags = true;
+ } else {
+ this._hasBugFlags = true;
+ }
+ // don't break as there may be multiple flag changes at once
+ }
+ }
+ },
+
+ linkAttachmentFlags: function() {
+ var rows = Dom.get('attachment_table').getElementsByTagName('tr');
+ for (var i = 0, il = rows.length; i < il; i++) {
+
+ // deal with attachments with flags only
+ var tr = rows[i];
+ if (!tr.id || tr.id == 'a0')
+ continue;
+ var attachFlagTd = Dom.getElementsByClassName('bz_attach_flags', 'td', tr);
+ if (attachFlagTd.length == 0)
+ continue;
+ attachFlagTd = attachFlagTd[0];
+
+ // get the attachment id
+ var attachId = 0;
+ var anchors = tr.getElementsByTagName('a');
+ for (var j = 0, jl = anchors.length; j < jl; j++) {
+ var match = anchors[j].href.match(/attachment\.cgi\?id=(\d+)/);
+ if (match) {
+ attachId = match[1];
+ break;
+ }
+ }
+ if (!attachId)
+ continue;
+
+ var html = '';
+
+ // there may be multiple flags, split by <br>
+ var attachFlags = attachFlagTd.innerHTML.split('<br>');
+ for (var j = 0, jl = attachFlags.length; j < jl; j++) {
+ var match = attachFlags[j].match(/^\s*(<span.+\/span>):([^\?\-\+]+[\?\-\+])([\s\S]*)/);
+ if (!match) continue;
+ var setterSpan = match[1];
+ var flag = this.trim(match[2].replace('\u2011', '-', 'g'));
+ var requestee = this.trim(match[3]);
+ var requesteeLogin = '';
+
+ match = setterSpan.match(/title="([^"]+)"/);
+ if (!match) continue;
+ var setterIdentity = this.htmlDecode(match[1]);
+
+ if (requestee) {
+ match = requestee.match(/title="([^"]+)"/);
+ if (!match) continue;
+ requesteeLogin = this.htmlDecode(match[1]);
+ match = requesteeLogin.match(/<([^>]+)>/);
+ if (!match) continue;
+ requesteeLogin = match[1];
+ }
+
+ var flagValue = requestee ? flag + '(' + requesteeLogin + ')' : flag;
+ // find the id for this change
+ var found = false;
+ for (var k = 0, kl = ih_activity_flags.length; k < kl; k++) {
+ flagItem = ih_activity_flags[k];
+ if (
+ flagItem[2] == attachId
+ && flagItem[3] == flagValue
+ && flagItem[4] == setterIdentity
+ ) {
+ html +=
+ setterSpan + ': '
+ + '<a href="#' + flagItem[5] + '">' + flag + '</a>'
+ + requestee + '<br>';
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // something went wrong, insert the flag unlinked
+ html += attachFlags[j] + '<br>';
+ }
+ }
+
+ if (html)
+ attachFlagTd.innerHTML = html;
+ }
+ },
+
+ linkBugFlags: function() {
+ var rows = Dom.get('flags').getElementsByTagName('tr');
+ for (var i = 0, il = rows.length; i < il; i++) {
+ var cells = rows[i].getElementsByTagName('td');
+ if (!cells[1]) continue;
+
+ var match = cells[0].innerHTML.match(/title="([^"]+)"/);
+ if (!match) continue;
+ var setterIdentity = this.htmlDecode(match[1]);
+
+ var flagValue = cells[2].getElementsByTagName('select');
+ if (!flagValue.length) continue;
+ flagValue = flagValue[0].value;
+
+ var flagLabel = cells[1].getElementsByTagName('label');
+ if (!flagLabel.length) continue;
+ flagLabel = flagLabel[0];
+ var flagName = this.trim(flagLabel.innerHTML).replace('\u2011', '-', 'g');
+
+ for (var j = 0, jl = ih_activity_flags.length; j < jl; j++) {
+ flagItem = ih_activity_flags[j];
+ if (
+ !flagItem[2]
+ && flagItem[3] == flagName + flagValue
+ && flagItem[4] == setterIdentity
+ ) {
+ flagLabel.innerHTML =
+ '<a href="#' + flagItem[5] + '">' + flagName + '</a>';
+ break;
+ }
+ }
+ }
+ },
+
+ hideCC: function() {
+ Dom.addClass(this._ccDivs, 'ih_hidden');
+ },
+
+ showCC: function() {
+ Dom.removeClass(this._ccDivs, 'ih_hidden');
+ },
+
+ addCCtoggler: function() {
+ var ul = Dom.getElementsByClassName('bz_collapse_expand_comments');
+ if (ul.length == 0)
+ return;
+ ul = ul[0];
+ var a = document.createElement('a');
+ a.href = 'javascript:void(0)';
+ a.id = 'ih_toggle_cc';
+ YAHOO.util.Event.addListener(a, 'click', function(e) {
+ if (Dom.get('ih_toggle_cc').innerHTML == 'Show CC Changes') {
+ a.innerHTML = 'Hide CC Changes';
+ inline_history.showCC();
+ } else {
+ a.innerHTML = 'Show CC Changes';
+ inline_history.hideCC();
+ }
+ });
+ a.innerHTML = 'Show CC Changes';
+ var li = document.createElement('li');
+ li.appendChild(a);
+ ul.appendChild(li);
+ },
+
+ previousElementSibling: function(el) {
+ if (el.previousElementSibling)
+ return el.previousElementSibling;
+ while (el = el.previousSibling) {
+ if (el.nodeType == 1)
+ return el;
+ }
+ },
+
+ nextElementSibling: function(el) {
+ if (el.nextElementSibling)
+ return el.nextElementSibling;
+ while (el = el.nextSibling) {
+ if (el.nodeType == 1)
+ return el;
+ }
+ },
+
+ htmlDecode: function(v) {
+ var e = document.createElement('div');
+ e.innerHTML = v;
+ return e.childNodes.length == 0 ? '' : e.childNodes[0].nodeValue;
+ },
+
+ trim: function(s) {
+ return s.replace(/^\s+|\s+$/g, '');
+ }
+}
diff --git a/extensions/InlineHistory/web/style.css b/extensions/InlineHistory/web/style.css
new file mode 100644
index 000000000..bca3a197b
--- /dev/null
+++ b/extensions/InlineHistory/web/style.css
@@ -0,0 +1,54 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+ * the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is the InlineHistory Bugzilla Extension;
+ * Derived from the Bugzilla Tweaks Addon.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011 the Initial
+ * Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Johnathan Nightingale <johnath@mozilla.com>
+ * Ehsan Akhgari <ehsan@mozilla.com>
+ * Byron Jones <glob@mozilla.com>
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+.ih_history {
+ background: none !important;
+ color: #444;
+}
+
+.ih_inlinehistory {
+ font-weight: normal;
+ font-size: small;
+ color: #444;
+ border-top: 1px dotted #C8C8BA;
+ padding-top: 5px;
+}
+
+.bz_comment.ih_history {
+ padding: 5px 5px 0px 5px
+}
+
+.ih_history_item {
+ margin-bottom: 5px;
+}
+
+.ih_hidden {
+ display: none;
+}
+
+.ih_deleted {
+ text-decoration: line-through;
+}
diff --git a/extensions/REMO/Config.pm b/extensions/REMO/Config.pm
new file mode 100644
index 000000000..625e2afd9
--- /dev/null
+++ b/extensions/REMO/Config.pm
@@ -0,0 +1,34 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the REMO Bugzilla Extension.
+#
+# The Initial Developer of the Original Code is Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011 the
+# Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Byron Jones <glob@mozilla.com>
+# David Lawrence <dkl@mozilla.com>
+
+package Bugzilla::Extension::REMO;
+use strict;
+
+use constant NAME => 'REMO';
+
+use constant REQUIRED_MODULES => [
+];
+
+use constant OPTIONAL_MODULES => [
+];
+
+__PACKAGE__->NAME;
diff --git a/extensions/REMO/Extension.pm b/extensions/REMO/Extension.pm
new file mode 100644
index 000000000..a0091281b
--- /dev/null
+++ b/extensions/REMO/Extension.pm
@@ -0,0 +1,184 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the REMO Bugzilla Extension.
+#
+# The Initial Developer of the Original Code is Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011 the
+# Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Byron Jones <glob@mozilla.com>
+# David Lawrence <dkl@mozilla.com>
+
+package Bugzilla::Extension::REMO;
+use strict;
+use base qw(Bugzilla::Extension);
+
+use Bugzilla::Constants;
+use Bugzilla::Util qw(trick_taint trim detaint_natural);
+use Bugzilla::Token;
+use Bugzilla::Error;
+
+our $VERSION = '0.01';
+
+sub page_before_template {
+ my ($self, $args) = @_;
+ my $page = $args->{'page_id'};
+ my $vars = $args->{'vars'};
+
+ if ($page eq 'remo-form-payment.html') {
+ _remo_form_payment($vars);
+ }
+}
+
+sub _remo_form_payment {
+ my ($vars) = @_;
+ my $input = Bugzilla->input_params;
+
+ my $user = Bugzilla->login(LOGIN_REQUIRED);
+
+ if ($input->{'action'} eq 'commit') {
+ my $template = Bugzilla->template;
+ my $cgi = Bugzilla->cgi;
+ my $dbh = Bugzilla->dbh;
+
+ my $bug_id = $input->{'bug_id'};
+ detaint_natural($bug_id);
+ my $bug = Bugzilla::Bug->check($bug_id);
+
+ # Detect if the user already used the same form to submit again
+ my $token = trim($input->{'token'});
+ if ($token) {
+ my ($creator_id, $date, $old_attach_id) = Bugzilla::Token::GetTokenData($token);
+ if (!$creator_id
+ || $creator_id != $user->id
+ || $old_attach_id !~ "^remo_form_payment:")
+ {
+ # The token is invalid.
+ ThrowUserError('token_does_not_exist');
+ }
+
+ $old_attach_id =~ s/^remo_form_payment://;
+ if ($old_attach_id) {
+ ThrowUserError('remo_payment_cancel_dupe',
+ { bugid => $bug_id, attachid => $old_attach_id });
+ }
+ }
+
+ # Make sure the user can attach to this bug
+ if (!$bug->user->{'canedit'}) {
+ ThrowUserError("remo_payment_bug_edit_denied",
+ { bug_id => $bug->id });
+ }
+
+ # Make sure the bug is under the correct product/component
+ if ($bug->product ne 'Mozilla Reps'
+ || $bug->component ne 'Budget Requests')
+ {
+ ThrowUserError('remo_payment_invalid_product');
+ }
+
+ my ($timestamp) = $dbh->selectrow_array("SELECT NOW()");
+
+ $dbh->bz_start_transaction;
+
+ # Create the comment to be added based on the form fields from rep-payment-form
+ my $comment;
+ $template->process("pages/comment-remo-form-payment.txt.tmpl", $vars, \$comment)
+ || ThrowTemplateError($template->error());
+ $bug->add_comment($comment, { isprivate => 0 });
+
+ # Attach expense report
+ # FIXME: Would be nice to be able to have the above prefilled comment and
+ # the following attachments all show up under a single comment. But the longdescs
+ # table can only handle one attach_id per comment currently. At least only one
+ # email is sent the way it is done below.
+ my $attachment;
+ if (defined $cgi->upload('expenseform')) {
+ # Determine content-type
+ my $content_type = $cgi->uploadInfo($cgi->param('expenseform'))->{'Content-Type'};
+
+ $attachment = Bugzilla::Attachment->create(
+ { bug => $bug,
+ creation_ts => $timestamp,
+ data => $cgi->upload('expenseform'),
+ description => 'Expense Form',
+ filename => scalar $cgi->upload('expenseform'),
+ ispatch => 0,
+ isprivate => 0,
+ isurl => 0,
+ mimetype => $content_type,
+ store_in_file => 0,
+ });
+
+ # Insert comment for attachment
+ $bug->add_comment('', { isprivate => 0,
+ type => CMT_ATTACHMENT_CREATED,
+ extra_data => $attachment->id });
+ }
+
+ # Attach receipts file
+ if (defined $cgi->upload("receipts")) {
+ # Determine content-type
+ my $content_type = $cgi->uploadInfo($cgi->param("receipts"))->{'Content-Type'};
+
+ $attachment = Bugzilla::Attachment->create(
+ { bug => $bug,
+ creation_ts => $timestamp,
+ data => $cgi->upload('receipts'),
+ description => "Receipts",
+ filename => scalar $cgi->upload("receipts"),
+ ispatch => 0,
+ isprivate => 0,
+ isurl => 0,
+ mimetype => $content_type,
+ store_in_file => 0,
+ });
+
+ # Insert comment for attachment
+ $bug->add_comment('', { isprivate => 0,
+ type => CMT_ATTACHMENT_CREATED,
+ extra_data => $attachment->id });
+ }
+
+ $bug->update($timestamp);
+
+ if ($token) {
+ trick_taint($token);
+ $dbh->do('UPDATE tokens SET eventdata = ? WHERE token = ?', undef,
+ ("remo_form_payment:" . $attachment->id, $token));
+ }
+
+ $dbh->bz_commit_transaction;
+
+ # Define the variables and functions that will be passed to the UI template.
+ $vars->{'attachment'} = $attachment;
+ $vars->{'bugs'} = [ new Bugzilla::Bug($bug_id) ];
+ $vars->{'header_done'} = 1;
+ $vars->{'contenttypemethod'} = 'autodetect';
+
+ my $recipients = { 'changer' => $user };
+ $vars->{'sent_bugmail'} = Bugzilla::BugMail::Send($bug_id, $recipients);
+
+ print $cgi->header();
+ # Generate and return the UI (HTML page) from the appropriate template.
+ $template->process("attachment/created.html.tmpl", $vars)
+ || ThrowTemplateError($template->error());
+ exit;
+ }
+ else {
+ $vars->{'token'} = issue_session_token('remo_form_payment:');
+ }
+}
+
+__PACKAGE__->NAME;
diff --git a/extensions/BMO/template/en/default/bug/create/comment-mozreps.txt.tmpl b/extensions/REMO/template/en/default/bug/create/comment-mozreps.txt.tmpl
index 6c9d7c6b7..29544d669 100644
--- a/extensions/BMO/template/en/default/bug/create/comment-mozreps.txt.tmpl
+++ b/extensions/REMO/template/en/default/bug/create/comment-mozreps.txt.tmpl
@@ -8,7 +8,7 @@
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
- # The Original Code is the BMO Bugzilla Extension.
+ # The Original Code is the REMO Bugzilla Extension.
#
# The Initial Developer of the Original Code is the Mozilla Foundation
# Portions created by the Initial Developers are Copyright (C) 2011 the
diff --git a/extensions/BMO/template/en/default/bug/create/comment-remo-budget.txt.tmpl b/extensions/REMO/template/en/default/bug/create/comment-remo-budget.txt.tmpl
index 9486c56fe..9486c56fe 100644
--- a/extensions/BMO/template/en/default/bug/create/comment-remo-budget.txt.tmpl
+++ b/extensions/REMO/template/en/default/bug/create/comment-remo-budget.txt.tmpl
diff --git a/extensions/BMO/template/en/default/bug/create/comment-remo-swag.txt.tmpl b/extensions/REMO/template/en/default/bug/create/comment-remo-swag.txt.tmpl
index 0b98178b2..985a8924d 100644
--- a/extensions/BMO/template/en/default/bug/create/comment-remo-swag.txt.tmpl
+++ b/extensions/REMO/template/en/default/bug/create/comment-remo-swag.txt.tmpl
@@ -30,23 +30,27 @@
Requester info:
-Requester name: [% cgi.param('firstname') %][% " " %][% cgi.param('lastname') %]
+First name: [% cgi.param('firstname') %]
+Last name: [% cgi.param('lastname') %]
Wiki user profile: [% cgi.param('wikiprofile') %]
+Event name: [% cgi.param('eventname') %]
Event wiki page: [% cgi.param('wikipage') %]
-Estimated Attendance: [% cgi.param('attendance') %]
+Estimated attendance: [% cgi.param('attendance') %]
Shipping details:
-Ship swag before: [% cgi.param('shipdate') %]
-
-[%+ cgi.param("shiptofirstname") +%] [%+ cgi.param("shiptolastname") +%]
-[%+ cgi.param("shiptoaddress") +%]
-[%+ cgi.param("shiptoaddress2") +%]
-[%+ cgi.param("shiptocity") +%] [%+ cgi.param("shiptostate") +%] [%+ cgi.param("shiptopcode") +%]
-[%+ cgi.param("shiptocountry") %]
+Ship swag before: [% cgi.param('cf_due_date') %]
+First name: [% cgi.param("shiptofirstname") %]
+Last name: [% cgi.param("shiptolastname") %]
+Address line 1: [% cgi.param("shiptoaddress1") %]
+Address line 2: [% cgi.param("shiptoaddress2") %]
+City: [% cgi.param("shiptocity") %]
+State/Region: [% cgi.param("shiptostate") %]
+Postal code: [% cgi.param("shiptopcode") %]
+Country: [% cgi.param("shiptocountry") %]
Phone: [% cgi.param("shiptophone") %]
-[%+ IF cgi.param("shiptoidrut") %]Personal ID/RUT: [% cgi.param("shiptoidrut") %][% END %]
+[%+ IF cgi.param("shiptoidrut") %]Custom reference: [% cgi.param("shiptoidrut") %][% END %]
Addition information for delivery person:
[%+ cgi.param('shipadditional') %]
diff --git a/extensions/BMO/template/en/default/bug/create/create-mozreps.html.tmpl b/extensions/REMO/template/en/default/bug/create/create-mozreps.html.tmpl
index 914e1f54d..8b126f9dd 100644
--- a/extensions/BMO/template/en/default/bug/create/create-mozreps.html.tmpl
+++ b/extensions/REMO/template/en/default/bug/create/create-mozreps.html.tmpl
@@ -8,7 +8,7 @@
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
- # The Original Code is the BMO Bugzilla Extension.
+ # The Original Code is the REMO Bugzilla Extension.
#
# The Initial Developer of the Original Code is the Mozilla Foundation
# Portions created by the Initial Developers are Copyright (C) 2011 the
@@ -21,7 +21,7 @@
[% PROCESS global/header.html.tmpl
title = "Mozilla Reps - Application Form"
- style_urls = [ "extensions/BMO/web/styles/moz_reps.css" ]
+ style_urls = [ "extensions/REMO/web/styles/moz_reps.css" ]
%]
[% USE Bugzilla %]
@@ -92,12 +92,12 @@ function submitForm() {
<table id="reps-form">
<tr class="odd">
- <th>First Name:[% mandatory FILTER html %]</th>
+ <th>First Name:[% mandatory %]</th>
<td><input id="first_name" name="first_name" size="40" placeholder="John"></td>
</tr>
<tr class="even">
- <th>Last Name:[% mandatory FILTER html %]</th>
+ <th>Last Name:[% mandatory %]</th>
<td><input id="last_name" name="last_name" size="40" placeholder="Doe"></td>
</tr>
@@ -107,7 +107,7 @@ function submitForm() {
</tr>
<tr class="even">
- <th>Sex:[% mandatory FILTER html %]</th>
+ <th>Sex:[% mandatory %]</th>
<td>
<select id="sex" name="sex">
<option value="Male">Male</option>
@@ -118,12 +118,12 @@ function submitForm() {
</tr>
<tr class="odd">
- <th>City:[% mandatory FILTER html %]</th>
+ <th>City:[% mandatory %]</th>
<td><input id="city" name="city" size="40" placeholder="Your city"></td>
</tr>
<tr class="even">
- <th>Country:[% mandatory FILTER html %]</th>
+ <th>Country:[% mandatory %]</th>
<td><input id="country" name="country" size="40" placeholder="Your country"></td>
</tr>
@@ -161,17 +161,17 @@ function submitForm() {
</tr>
<tr class="odd">
- <th>Languages Spoken:[% mandatory FILTER html %]</th>
+ <th>Languages Spoken:[% mandatory %]</th>
<td><input id="languages" name="languages" size="40"></td>
</tr>
<tr class="even">
- <th>How did you learn about Mozilla Reps?[% mandatory FILTER html %]</th>
+ <th>How did you learn about Mozilla Reps?[% mandatory %]</th>
<td><input id="learn" name="learn" size="40"></td>
</tr>
<tr class="odd">
- <th colspan="2">What motivates you most about joining Mozilla Reps?[% mandatory FILTER html %]</th>
+ <th colspan="2">What motivates you most about joining Mozilla Reps?[% mandatory %]</th>
</tr>
<tr class="odd">
<td colspan="2"><textarea id="motivation" name="motivation" rows="4"></textarea></td>
@@ -187,7 +187,7 @@ function submitForm() {
<tr class="odd">
<th>
I have read the
- <a href="http://www.mozilla.com/en-US/privacy-policy" target="_blank">Mozilla Privacy Policy</a>:[% mandatory FILTER html %]
+ <a href="http://www.mozilla.com/en-US/privacy-policy" target="_blank">Mozilla Privacy Policy</a>:[% mandatory %]
</th>
<td><input id="privacy" type="checkbox"></td>
</tr>
diff --git a/extensions/BMO/template/en/default/bug/create/create-remo-budget.html.tmpl b/extensions/REMO/template/en/default/bug/create/create-remo-budget.html.tmpl
index 0aa18e41d..267b25e3a 100644
--- a/extensions/BMO/template/en/default/bug/create/create-remo-budget.html.tmpl
+++ b/extensions/REMO/template/en/default/bug/create/create-remo-budget.html.tmpl
@@ -23,12 +23,14 @@
[% PROCESS global/header.html.tmpl
title = "Mozilla Reps Budget Request Form"
- style_urls = [ 'extensions/BMO/web/styles/moz_reps.css' ]
- javascript_urls = [ 'extensions/BMO/web/js/form_validate.js',
+ style_urls = [ 'extensions/REMO/web/styles/moz_reps.css' ]
+ javascript_urls = [ 'extensions/REMO/web/js/form_validate.js',
'js/util.js',
'js/field.js' ]
%]
+[% IF user.in_group("mozilla-reps") %]
+
<p>These requests will only be visible to the person who submitted the request,
any persons designated in the CC line, and authorized members of the Mozilla
Rep team.</p>
@@ -245,4 +247,8 @@ function togglePaymentInfo (e) {
Thanks for contacting us.
</p>
+[% ELSE %]
+ <p>Sorry, you do not have access to this page.</p>
+[% END %]
+
[% PROCESS global/footer.html.tmpl %]
diff --git a/extensions/BMO/template/en/default/bug/create/create-remo-swag.html.tmpl b/extensions/REMO/template/en/default/bug/create/create-remo-swag.html.tmpl
index 0b15240fd..ae24e667a 100644
--- a/extensions/BMO/template/en/default/bug/create/create-remo-swag.html.tmpl
+++ b/extensions/REMO/template/en/default/bug/create/create-remo-swag.html.tmpl
@@ -23,24 +23,23 @@
[% PROCESS global/header.html.tmpl
title = "Mozilla Reps Swag Request Form"
- javascript_urls = [ 'extensions/BMO/web/js/swag.js',
- 'extensions/BMO/web/js/form_validate.js',
+ javascript_urls = [ 'extensions/REMO/web/js/swag.js',
+ 'extensions/REMO/web/js/form_validate.js',
'js/field.js',
'js/util.js' ]
- style_urls = [ "extensions/BMO/web/styles/moz_reps.css",
- "skins/custom/calendar.css" ]
+ style_urls = [ "extensions/REMO/web/styles/moz_reps.css" ]
yui = [ 'calendar' ]
%]
+[% IF user.in_group("mozilla-reps") %]
+
<p>These requests will only be visible to the person who submitted the request,
any persons designated in the CC line, and authorized members of the Mozilla Rep team.</p>
<script language="javascript" type="text/javascript">
function trySubmit() {
- var firstname = document.getElementById('firstname').value;
- var lastname = document.getElementById('lastname').value;
- var requester = firstname + ' ' + lastname;
- var shortdesc = 'Swag Request - ' + requester;
+ var eventname = document.getElementById('eventname').value;
+ var shortdesc = 'Swag Request - ' + eventname;
document.getElementById('short_desc').value = shortdesc;
return true;
}
@@ -50,11 +49,12 @@ function validateAndSubmit() {
if(!isFilledOut('firstname')) alert_text += "Please enter your first name\n";
if(!isFilledOut('lastname')) alert_text += "Please enter your last name\n";
if(!isFilledOut('wikiprofile')) alert_text += "Please enter your wiki user profile\n";
+ if(!isFilledOut('eventname')) alert_text += "Please enter your event name\n";
if(!isFilledOut('wikipage')) alert_text += "Please enter the event wiki page.\n";
if(!isFilledOut('attendance')) alert_text += "Please enter the estimated attendance.\n";
if(!isFilledOut('shiptofirstname')) alert_text += "Please enter the shipping first name\n";
if(!isFilledOut('shiptolastname')) alert_text += "Please enter the shipping last name\n";
- if(!isFilledOut('shiptoaddress')) alert_text += "Please enter the ship to address\n";
+ if(!isFilledOut('shiptoaddress1')) alert_text += "Please enter the ship to address\n";
if(!isFilledOut('shiptocity')) alert_text += "Please enter the ship to city\n";
if(!isFilledOut('shiptocountry')) alert_text += "Please enter the ship to country\n";
if(!isFilledOut('shiptopcode')) alert_text += "Please enter the ship to postal code\n";
@@ -112,6 +112,13 @@ function validateAndSubmit() {
</tr>
<tr class="even">
+ <td><strong>Event Name: <span style="color: red;" title="Required">*</span></strong></td>
+ <td>
+ <input type="text" name="eventname" id="eventname" size="40">
+ </td>
+</tr>
+
+<tr class="odd">
<td><strong>Event Wiki Page: <span style="color: red;" title="Required">*</span></strong></td>
<td>
<input type="text" name="wikipage" id="wikipage" size="40">
@@ -121,7 +128,12 @@ function validateAndSubmit() {
<tr class="even">
<td><strong>Estimated Attendance: <span style="color: red;" title="Required">*</span></strong></td>
<td>
- <input type="text" name="attendance" id="attendance" size="40">
+ <select id="attendance" name="attendance">
+ <option value="1-50">1-50</option>
+ <option value="51-200">51-200</option>
+ <option value="201-500">201-500</option>
+ <option value="501-1000+">501-1000+</option>
+ </select>
</td>
</tr
@@ -137,12 +149,13 @@ function validateAndSubmit() {
<tr class="odd">
<td><strong>Ship Before:</strong>
<td>
- <input type="text" id="shipdate" name="shipdate" size="10"
- onchange="updateCalendarFromField(this)">
- <button type="button" class="calendar_button" id="button_calendar_date"
- onclick="showCalendar('shipdate')"><span>Calendar</span>
- </button>
- <div id="con_calendar_shipdate"></div>
+ [% INCLUDE bug/field.html.tmpl
+ bug = default,
+ field = bug_fields.cf_due_date
+ value = default.cf_due_date,
+ editable = 1,
+ no_tds = 1
+ %]
</td>
</tr>
@@ -157,12 +170,12 @@ function validateAndSubmit() {
</tr>
<tr class="even">
- <td><strong>Address: <span style="color: red;" title="Required">*</span></strong></td>
- <td><input name="shiptoaddress" id="shiptoaddress" placeholder="123 Main St." size="40"></td>
+ <td><strong>Address Line 1: <span style="color: red;" title="Required">*</span></strong></td>
+ <td><input name="shiptoaddress1" id="shiptoaddress1" placeholder="123 Main St." size="40"></td>
</tr>
<tr class="odd">
- <td><strong>Address 2:</strong></td>
+ <td><strong>Address Line 2:</strong></td>
<td><input name="shiptoaddress2" id="shiptoaddress2" size="40"></td>
</tr>
@@ -172,7 +185,7 @@ function validateAndSubmit() {
</tr>
<tr class="odd">
- <td><strong>State:</strong></td>
+ <td><strong>State/Region (if applicable):</strong></td>
<td><input name="shiptostate" id="shiptostate" placeholder="CA" size="40"></td>
</tr>
@@ -187,12 +200,12 @@ function validateAndSubmit() {
</tr>
<tr class="even">
- <td><strong>Contact Number: <span style="color: red;" title="Required">*</span></strong></td>
+ <td><strong>Phone (including country code): <span style="color: red;" title="Required">*</span></strong></td>
<td><input name="shiptophone" id="shiptophone" placeholder="919-555-1212" size="40"></td>
</tr>
<tr class="odd">
- <td><strong>Personal ID/RUT:</strong><br><small>(if your country requires this)</small></td>
+ <td><strong>Custom Reference (Fiscal or VAT-number, if known):</strong><br><small>(if your country requires this)</small></td>
<td><input name="shiptoidrut" id="shiptoidrut" size="40"></td>
</tr>
@@ -203,16 +216,16 @@ function validateAndSubmit() {
</td>
</tr>
-<tr class="odd">
+<tr class="even">
<td><!--spacer-->&nbsp;</td>
<td><!--spacer-->&nbsp;</td>
</tr>
-<tr class="even">
+<tr class="odd">
<td colspan="2"><strong>Swag Requested:</strong></td>
</tr>
-<tr class="odd">
+<tr class="even">
<td><strong>Stickers:</strong></td>
<td><input type="checkbox" id="stickers" name="stickers" value="1"></td>
</tr>
@@ -285,8 +298,8 @@ function validateAndSubmit() {
You will be notified by email of any progress made in resolving your request.
</p>
-<script type="text/javascript">
- createCalendar('shipdate');
-</script>
+[% ELSE %]
+ <p>Sorry, you do not have access to this page.</p>
+[% END %]
[% PROCESS global/footer.html.tmpl %]
diff --git a/extensions/REMO/template/en/default/bug/create/created-mozreps.html.tmpl b/extensions/REMO/template/en/default/bug/create/created-mozreps.html.tmpl
new file mode 100644
index 000000000..378ab45d0
--- /dev/null
+++ b/extensions/REMO/template/en/default/bug/create/created-mozreps.html.tmpl
@@ -0,0 +1,38 @@
+[%# The contents of this file are subject to the Mozilla Public
+ # License Version 1.1 (the "License"); you may not use this file
+ # except in compliance with the License. You may obtain a copy of
+ # the License at http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS
+ # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # rights and limitations under the License.
+ #
+ # The Original Code is the REMO Bugzilla Extension.
+ #
+ # The Initial Developer of the Original Code is the Mozilla Foundation
+ # Portions created by the Initial Developers are Copyright (C) 2011 the
+ # Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s): Byron Jones <glob@mozilla.com>
+ #%]
+
+[% PROCESS global/variables.none.tmpl %]
+
+[% PROCESS global/header.html.tmpl
+ title = "Mozilla Reps - Application Form"
+
+%]
+
+<h1>Thank you!</h1>
+
+<p>
+Thank you for submitting your Mozilla Reps Application Form. A Mozilla Rep
+mentor will contact you shortly at your bugzilla email address.
+</p>
+
+<p style="font-size: x-small">
+Reference: <a href="show_bug.cgi?id=[% id %]">#[% id %]</a>
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/extensions/REMO/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/REMO/template/en/default/hook/global/user-error-errors.html.tmpl
new file mode 100644
index 000000000..200e678be
--- /dev/null
+++ b/extensions/REMO/template/en/default/hook/global/user-error-errors.html.tmpl
@@ -0,0 +1,40 @@
+[%# The contents of this file are subject to the Mozilla Public
+ # License Version 1.1 (the "License"); you may not use this file
+ # except in compliance with the License. You may obtain a copy of
+ # the License at http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS
+ # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ # implied. See the License for the specific language governing
+ # rights and limitations under the License.
+ #
+ # The Original Code is the REMO Extension
+ #
+ # The Initial Developer of the Original Code is the Mozilla Foundation
+ # Portions created by the Initial Developers are Copyright (C) 2011 the
+ # Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s):
+ # Byron Jones <bjones@mozilla.com>
+ # David Lawrence <dkl@mozilla.com>
+ #%]
+
+[% IF error == "remo_payment_invalid_product" %]
+ [% title = "Mozilla Reps Payment Invalid Bug" %]
+ You can only attach budget payment information to [% terms.bugs %] under
+ the product 'Mozilla Reps' and component 'Budget Requests'.
+
+[% ELSIF error == "remo_payment_bug_edit_denied" %]
+ [% title = "Mozilla Reps Payment Bug Edit Denied" %]
+ You do not have permission to edit [% terms.bug %] '[% bug_id FILTER html %]'.
+
+[% ELSIF error == "remo_payment_cancel_dupe" %]
+ [% title = "Already filed payment request" %]
+ You already used the form to file
+ <a href="[% urlbase FILTER html %]attachment.cgi?id=[% attachid FILTER uri %]&action=edit">
+ attachment [% attachid FILTER uri %]</a>.<br>
+ <br>
+ You can either <a href="[% urlbase FILTER html %]page.cgi?id=remo-form-payment.html">
+ create a new payment request</a> or [% "go back to $terms.bug $bugid" FILTER bug_link(bugid) FILTER none %].
+
+[% END %]
diff --git a/extensions/BMO/template/en/default/pages/comment-remo-form-payment.txt.tmpl b/extensions/REMO/template/en/default/pages/comment-remo-form-payment.txt.tmpl
index c43a92ae7..95c0af6e8 100644
--- a/extensions/BMO/template/en/default/pages/comment-remo-form-payment.txt.tmpl
+++ b/extensions/REMO/template/en/default/pages/comment-remo-form-payment.txt.tmpl
@@ -8,7 +8,7 @@
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
- # The Original Code is the BMO Extension
+ # The Original Code is the REMO Extension
#
# The Initial Developer of the Original Code is the Mozilla Foundation
# Portions created by the Initial Developers are Copyright (C) 2011 the
diff --git a/extensions/BMO/template/en/default/pages/remo-form-payment.html.tmpl b/extensions/REMO/template/en/default/pages/remo-form-payment.html.tmpl
index ae4ca6f2e..0f5f206d3 100644
--- a/extensions/BMO/template/en/default/pages/remo-form-payment.html.tmpl
+++ b/extensions/REMO/template/en/default/pages/remo-form-payment.html.tmpl
@@ -8,7 +8,7 @@
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
- # The Original Code is the BMO Extension
+ # The Original Code is the REMO Extension
#
# The Initial Developer of the Original Code is the Mozilla Foundation
# Portions created by the Initial Developers are Copyright (C) 2011 the
@@ -22,8 +22,8 @@
[% PROCESS global/header.html.tmpl
title = "Mozilla Reps Payment Form"
- style_urls = [ 'extensions/BMO/web/styles/moz_reps.css' ]
- javascript_urls = [ 'extensions/BMO/web/js/form_validate.js',
+ style_urls = [ 'extensions/REMO/web/styles/moz_reps.css' ]
+ javascript_urls = [ 'extensions/REMO/web/js/form_validate.js',
'js/util.js',
'js/field.js' ]
yui = ['connection', 'json']
@@ -39,7 +39,7 @@ function validateAndSubmit() {
if(!isFilledOut('lastname')) alert_text += "Please enter your last name\n";
if(!isFilledOut('wikiprofile')) alert_text += "Please enter a wiki user profile.\n";
if(!isFilledOut('wikipage')) alert_text += "Please enter a wiki page address.\n";
- if(!isFilledOut('bug_id')) alert_text += "Please enter a valid [%terms.bug %] id to attach this additional information to.\n";
+ if(!isFilledOut('bug_id')) alert_text += "Please enter a valid [% terms.bug %] id to attach this additional information to.\n";
if(!isFilledOut('expenseform')) alert_text += "Please enter an expense form to upload.\n";
if(!isFilledOut('receipts')) alert_text += "Please enter a receipts file to upload.\n";
@@ -101,7 +101,7 @@ function getBugInfo (e, div) {
"'Mozilla Reps' and component 'Budget Requests'.";
}
else {
- bug_message = "Bug " + bug_id + " - " + data.result.bugs[0].status +
+ bug_message = "[% terms.Bug %] " + bug_id + " - " + data.result.bugs[0].status +
" - " + data.result.bugs[0].summary;
}
}
diff --git a/extensions/REMO/web/js/form_validate.js b/extensions/REMO/web/js/form_validate.js
new file mode 100644
index 000000000..6c8fa6f07
--- /dev/null
+++ b/extensions/REMO/web/js/form_validate.js
@@ -0,0 +1,21 @@
+/**
+ * Some Form Validation and Interaction
+ **/
+//Makes sure that there is an '@' in the address with a '.'
+//somewhere after it (and at least one character in between them
+
+function isValidEmail(email) {
+ var at_index = email.indexOf("@");
+ var last_dot = email.lastIndexOf(".");
+ return at_index > 0 && last_dot > (at_index + 1);
+}
+
+//Takes a DOM element id and makes sure that it is filled out
+function isFilledOut(elem_id) {
+ var str = document.getElementById(elem_id).value;
+ return str.length>0 && str!="noneselected";
+}
+
+function isChecked(elem_id) {
+ return document.getElementById(elem_id).checked;
+}
diff --git a/extensions/REMO/web/js/swag.js b/extensions/REMO/web/js/swag.js
new file mode 100644
index 000000000..47886b2a9
--- /dev/null
+++ b/extensions/REMO/web/js/swag.js
@@ -0,0 +1,60 @@
+/**
+ * Swag Request Form Functions
+ * Form Interal Swag Request Form
+ * dtran
+ * 7/6/09
+ **/
+
+
+function evalToNumber(numberString) {
+ if(numberString=='') return 0;
+ return parseInt(numberString);
+}
+
+function evalToNumberString(numberString) {
+ if(numberString=='') return '0';
+ return numberString;
+}
+//item_array should be an array of DOM element ids
+function getTotal(item_array) {
+ var total = 0;
+ for(var i in item_array) {
+ total += evalToNumber(document.getElementById(item_array[i]).value);
+ }
+ return total;
+}
+
+function calculateTotalSwag() {
+ document.getElementById('Totalswag').value =
+ getTotal( new Array('Lanyards',
+ 'Stickers',
+ 'Bracelets',
+ 'Tattoos',
+ 'Buttons',
+ 'Posters'));
+
+}
+
+
+function calculateTotalMensShirts() {
+ document.getElementById('mens_total').value =
+ getTotal( new Array('mens_s',
+ 'mens_m',
+ 'mens_l',
+ 'mens_xl',
+ 'mens_xxl',
+ 'mens_xxxl'));
+
+}
+
+
+function calculateTotalWomensShirts() {
+ document.getElementById('womens_total').value =
+ getTotal( new Array('womens_s',
+ 'womens_m',
+ 'womens_l',
+ 'womens_xl',
+ 'womens_xxl',
+ 'womens_xxxl'));
+
+}
diff --git a/extensions/BMO/web/styles/moz_reps.css b/extensions/REMO/web/styles/moz_reps.css
index 989733c41..989733c41 100644
--- a/extensions/BMO/web/styles/moz_reps.css
+++ b/extensions/REMO/web/styles/moz_reps.css
diff --git a/extensions/SecureMail/template/en/default/account/prefs/securemail.html.tmpl b/extensions/SecureMail/template/en/default/account/prefs/securemail.html.tmpl
index 2b643c961..dadfbb537 100644
--- a/extensions/SecureMail/template/en/default/account/prefs/securemail.html.tmpl
+++ b/extensions/SecureMail/template/en/default/account/prefs/securemail.html.tmpl
@@ -17,14 +17,12 @@
# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org>
#%]
-<p>Some [% terms.bugs %] in this [% terms.Bugzilla %] are in groups the administrator has
-deemed 'secure'. This means emails containing information about those [% terms.bugs %]
+<p>Some bugs in this [% terms.Bugzilla %] are in groups the administrator has
+deemed 'secure'. This means emails containing information about those bugs
will only be sent encrypted. Enter your PGP/GPG public key or
-SMIME certificate here to receive full update emails for such [% terms.bugs %].</p>
+SMIME certificate here to receive full update emails for such bugs.</p>
-<p>If you are a member of a secure group, or if you enter a key here, your password reset email
-will also be sent to you encrypted. If you are a member of a secure group and do not enter a key,
-you will not be able to reset your password without the assistance of an administrator.</p>
+<p>If you are a member of a secure group, or if you enter a key here, your password reset email will also be sent to you encrypted. If you are a member of a secure group and do not enter a key, you will not be able to reset your password without the assistance of an administrator.</p>
<p><a href="page.cgi?id=securemail/help.html">More help is available</a>.</p>
diff --git a/extensions/SecureMail/template/en/default/pages/securemail/help.html.tmpl b/extensions/SecureMail/template/en/default/pages/securemail/help.html.tmpl
index 4e1a5c577..76525eac2 100644
--- a/extensions/SecureMail/template/en/default/pages/securemail/help.html.tmpl
+++ b/extensions/SecureMail/template/en/default/pages/securemail/help.html.tmpl
@@ -24,12 +24,12 @@
title = "SecureMail Help"
%]
-[% terms.Bugzilla %] considers certain groups as "secure". If a [% terms.bug %] is in one of those groups, [% terms.Bugzilla %]
-will not send unencrypted email about it. To receive encrypted email rather than just a "something changed" placeholder, you must provide either
+Bugzilla considers certain groups as "secure". If a bug is in one of those groups, Bugzilla will not send unencrypted
+email about it. To receive encrypted email rather than just a "something changed" placeholder, you must provide either
a S/MIME or a GPG/PGP key on the <a href="[% urlbase FILTER none %]userprefs.cgi?tab=securemail">SecureMail preferences tab</a>.<br>
<br>
In addition, if you have uploaded a S/MIME or GPG/PGP key using the <a href="[% urlbase FILTER none %]userprefs.cgi?tab=securemail">
-SecureMail preferences tab</a>, if you request your password to be reset, [% terms.Bugzilla %] will send the reset email encrypted and you will
+SecureMail preferences tab</a>, if you request your password to be reset, Bugzilla will send the reset email encrypted and you will
be required to decrypt it to view the reset instructions.
<h2>S/MIME</h2>
@@ -86,7 +86,7 @@ You’ll have to answer several questions:</p>
<p><code>gpg --armor --output pubkey.txt --export 'Your Name'</code></p>
-<p>Paste the contents of pubkey.txt into the SecureMail text field in [% terms.Bugzilla %].
+<p>Paste the contents of pubkey.txt into the SecureMail text field in Bugzilla.
<li>Configure your email client to use your associated private key to decrypt the encrypted emails. For Thunderbird, you need the <a href="https://addons.mozilla.org/en-us/thunderbird/addon/enigmail/">Enigmail</a> extension.</p>
</ol>
diff --git a/extensions/SiteMapIndex/Extension.pm b/extensions/SiteMapIndex/Extension.pm
index f0b2a57d8..f36fa8c81 100644
--- a/extensions/SiteMapIndex/Extension.pm
+++ b/extensions/SiteMapIndex/Extension.pm
@@ -101,7 +101,8 @@ sub install_filesystem {
| Bugzilla::Install::Filesystem::DIR_ALSO_WS_SERVE;
$recurse_dirs->{$sitemap_path} = {
- files => Bugzilla::Install::Filesystem::WS_SERVE,
+ files => Bugzilla::Install::Filesystem::CGI_WRITE
+ | Bugzilla::Install::Filesystem::DIR_ALSO_WS_SERVE,
dirs => Bugzilla::Install::Filesystem::DIR_CGI_WRITE
| Bugzilla::Install::Filesystem::DIR_ALSO_WS_SERVE
};
diff --git a/extensions/SiteMapIndex/lib/Util.pm b/extensions/SiteMapIndex/lib/Util.pm
index 3c322d8c7..6b5491d1c 100644
--- a/extensions/SiteMapIndex/lib/Util.pm
+++ b/extensions/SiteMapIndex/lib/Util.pm
@@ -112,8 +112,8 @@ sub generate_sitemap {
last if !@$bugs;
- # We only need the product links in the first sitemap file
- $products = [] if $filecount > 1;
+ # We only need the product links in the first sitemap file
+ $products = [] if $filecount > 1;
push(@$filelist, _generate_sitemap_file($extension_name, $filecount, $products, $bugs));
diff --git a/extensions/Splinter/lib/Util.pm b/extensions/Splinter/lib/Util.pm
index c8c0d52d2..1861d7ab6 100644
--- a/extensions/Splinter/lib/Util.pm
+++ b/extensions/Splinter/lib/Util.pm
@@ -21,8 +21,6 @@
package Bugzilla::Extension::Splinter::Util;
-use strict;
-
use Bugzilla;
use Bugzilla::Util;
@@ -68,9 +66,9 @@ sub get_review_url {
my $bug_id = $bug->id;
if (defined $absolute && $absolute) {
- my $urlbase = correct_urlbase();
- $urlbase =~ s!/$!! if $base =~ "^/";
- $base = $urlbase . $base;
+ my $urlbase = correct_urlbase();
+ $urlbase =~ s!/$!! if $base =~ "^/";
+ $base = $urlbase . $base;
}
if ($base =~ /\?/) {
@@ -95,12 +93,12 @@ sub munge_create_attachment {
my ($bug, $intro_text, $attach_id, $view_link) = @_;
if (attachment_id_is_patch ($attach_id)) {
- return ("$intro_text" .
+ return ("$intro_text" .
" View: $view_link\015\012" .
" Review: " . get_review_url($bug, $attach_id, 1) . "\015\012");
}
else {
- return ("$intro_text --> ($view_link)");
+ return ("$intro_text --> ($view_link)");
}
}
@@ -117,24 +115,24 @@ sub add_review_links_to_email {
if ($email->header('Subject') =~ /^\[Bug\s+(\d+)\]/
&& Bugzilla->user->can_see_bug($1))
{
- $bug = Bugzilla::Bug->new($1);
+ $bug = Bugzilla::Bug->new($1);
}
return unless defined $bug;
if ($body =~ /Review\s+of\s+attachment\s+\d+\s*:/) {
- $body =~ s~(Review\s+of\s+attachment\s+(\d+)\s*:)
+ $body =~ s~(Review\s+of\s+attachment\s+(\d+)\s*:)
~"$1\015\012 --> (" . get_review_url($bug, $2, 1) . ")"
~egx;
- $new_body = 1;
+ $new_body = 1;
}
if ($body =~ /Created attachment \d+\015\012 --> /) {
- $body =~ s~(Created\ attachment\ (\d+)\015\012)
+ $body =~ s~(Created\ attachment\ (\d+)\015\012)
\ -->\ \(([^\015\012]*)\)[^\015\012]*
~munge_create_attachment($bug, $1, $2, $3)
~egx;
- $new_body = 1;
+ $new_body = 1;
}
$email->body_set($body) if $new_body;
diff --git a/extensions/Splinter/template/en/default/pages/splinter.html.tmpl b/extensions/Splinter/template/en/default/pages/splinter.html.tmpl
index a05cc87f9..4728967c7 100644
--- a/extensions/Splinter/template/en/default/pages/splinter.html.tmpl
+++ b/extensions/Splinter/template/en/default/pages/splinter.html.tmpl
@@ -16,7 +16,6 @@
# Red Hat, Inc. All Rights Reserved.
#
# Contributor(s): Owen Taylor <otaylor@redhat.com>
- # David Lawrence <dkl@mozilla.com>
#%]
[% PROCESS global/header.html.tmpl
@@ -27,7 +26,6 @@
"js/yui/assets/skins/sam/datatable.css",
"extensions/Splinter/web/splinter.css" ]
javascript_urls = [ "js/yui/element/element-min.js",
- "js/yui/connection/connection-min.js",
"js/yui/container/container-min.js",
"js/yui/button/button-min.js",
"js/yui/json/json-min.js",
@@ -40,7 +38,7 @@
<script type="text/javascript">
Splinter.configBase = '[% urlbase FILTER none %][% Param('splinter_base') FILTER js %]';
- Splinter.configBugUrl = '[% urlbase FILTER none %]';
+ Splinter.configBugzillaUrl = '[% urlbase FILTER none %]';
Splinter.configHaveExtension = true;
Splinter.configHelp = '[% urlbase FILTER none %]page.cgi?id=splinter/help.html';
Splinter.configNote = '';
@@ -117,13 +115,14 @@
</div>
<div id="bugInfo" style="display: none;">
- <b>[% terms.Bug %] <a id="bugLink"><span id="bugId"></span></a>:</b>
+ <b>Bug <a id="bugLink"><span id="bugId"></span></a>:</b>
<span id="bugShortDesc"></span> -
<span id="bugReporter"></span> -
<span id="bugCreationDate"></span>
</div>
<div id="attachInfo" style="display:none;">
+ <span id="attachObsolete"></span>
<b>Attachment <a id="attachLink"><span id="attachId"></span></a>:</b>
<span id="attachDesc"></span> -
<span id="attachCreator"></span> -
@@ -139,7 +138,7 @@
<div id="error" style="display: none;"> </div>
<div id="enterBug" style="display: none;">
- [% terms.Bug %] to review:
+ Bug to review:
<input id="enterBugInput" />
<input id="enterBugGo" type="button" value="Go" />
<div id="chooseReview" style="display: none;">
@@ -168,7 +167,7 @@
<li>To comment on a specific lines in the patch, first select the filename from the file navigation links.</li>
<li>Then double click the line you want to review and a comment box will appear below the line.</li>
<li>When the review is complete and you publish it, the overview comment and all line specific comments with their context,
- will be combined together into a single review comment on the [% terms.bug %] report.</li>
+ will be combined together into a single review comment on the bug report.</li>
<li>For more detailed instructions, read the Splinter
<a id='helpLink' target='splinterHelp' href="[% urlbase FILTER none %]page.cgi?id=splinter/help.html">help page</a>.
</li>
@@ -234,7 +233,7 @@
</form>
<div id="buttonBox">
<span id="attachmentStatusSpan">Patch Status:
- <select id="attachmentStatus"> </select>
+ <select id="attachmentStatus"> </select>
</span>
<input id="publishButton" type="button" value="Publish" />
<input id="cancelButton" type="button" value="Cancel" />
diff --git a/extensions/Splinter/template/en/default/pages/splinter/help.html.tmpl b/extensions/Splinter/template/en/default/pages/splinter/help.html.tmpl
index bff004c8f..7c797c94d 100644
--- a/extensions/Splinter/template/en/default/pages/splinter/help.html.tmpl
+++ b/extensions/Splinter/template/en/default/pages/splinter/help.html.tmpl
@@ -25,15 +25,15 @@
<h2>Splinter Patch Review</h2>
<p>
- Splinter is an add-on for [% terms.Bugzilla %] to allow conveniently
+ Splinter is an add-on for Bugzilla to allow conveniently
reviewing patches that people have attached to
- [% terms.Bugzilla %]. <a href="http://fishsoup.net/software/splinter">More
+ Bugzilla. <a href="http://fishsoup.net/software/splinter">More
information about Splinter</a>.
</p>
<h3>The patch review view</h3>
<p>
If you get to Splinter by clicking on a link next to an
- attachment in [% terms.Bugzilla %], you are presented with the patch
+ attachment in Bugzilla, you are presented with the patch
review view. This view has a number of different pages that can
be switched between with the links at the top of the screen.
The first page is the Overview page, the other pages correspond to
@@ -69,31 +69,31 @@
</p>
<ul>
<li>
- An overall comment. The text area on the first page allows
- you to enter your overall thoughts on the [% terms.bug %].
+ An overall comment. The text area on the first page allows
+ you to enter your overall thoughts on the bug.
</li>
<li>
- Detailed comments on changes within the files. To comment on a
- line in a patch, double click on it, and a text area will open
- beneath that comment. When you are done, click the Save button
- to save your comment or the Cancel button to throw your
- comment away. You can double-click on a saved comment to start
- editing it again and make further changes.
+ Detailed comments on changes within the files. To comment on a
+ line in a patch, double click on it, and a text area will open
+ beneath that comment. When you are done, click the Save button
+ to save your comment or the Cancel button to throw your
+ comment away. You can double-click on a saved comment to start
+ editing it again and make further changes.
</li>
<li>
- A change to the attachment status. (This is specific to
- [% terms.Bugzilla %] instances that have attachment status, which is a
- non-upstream patch. It's somewhat similar to attachment flags,
- which splinter doesn't currently support displaying or
- changing.) This allows you to mark a patch as read to commit
- or needing additional work. This is done by changing the
- drop-down next to the Publish button.
+ A change to the attachment status. (This is specific to
+ Bugzilla instances that have attachment status, which is a
+ non-upstream patch. It's somewhat similar to attachment flags,
+ which splinter doesn't currently support displaying or
+ changing.) This allows you to mark a patch as read to commit
+ or needing additional work. This is done by changing the
+ drop-down next to the Publish button.
</li>
</ul>
<p>
Once you are done writing your review, go back to Overview page
and click the "Publish" button to submit it as a comment on the
- [% terms.bug %]. The comment will have a link back to the review page so
+ bug. The comment will have a link back to the review page so
that people can see your comments with the full context.
</p>
<h3>Saved drafts</h3>
@@ -122,31 +122,31 @@
<h3>Uploading patches for review</h3>
<p>
Splinter doesn't really care how patches are provided to
- [% terms.Bugzilla %], as long as they are well-formatted patches. If you are
+ Bugzilla, as long as they are well-formatted patches. If you are
using Git for version control, you can either format changes as
patches
using <a href="http://www.kernel.org/pub/software/scm/git/docs/git-format-patch.html">'git
- format-patch</a> and attach them manually to the [% terms.bug %], or you
+ format-patch</a> and attach them manually to the bug, or you
can
use <a href="http://fishsoup.net/software/git-bz">git-bz</a>.
git-bz is highly recommended; it automates most of the steps
- that Splinter can't handle: it files new [% terms.bugs %], attaches updated
- attachments to existing [% terms.bugs %], and closes [% terms.bugs %] when you push the
+ that Splinter can't handle: it files new bugs, attaches updated
+ attachments to existing bugs, and closes bugs when you push the
corresponding git commits to your central repository.
</p>
-<h3>The [% terms.bug %] review view</h3>
+<h3>The bug review view</h3>
<p>
Splinter also has a view where it shows all patches attached to
- the [% terms.bug %] with their status and links to review them. You are
+ the bug with their status and links to review them. You are
taken to this page after publishing a review. You can also get
- to this page with the [% terms.bug %] link in the upper-right corner of the
+ to this page with the bug link in the upper-right corner of the
patch review view.
</p>
<h3>Your reviews</h3>
<p>
Splinter can also show you a list of all your draft and
published reviews. Access this page with the "Your reviews"
- link at the bottom of the [% terms.bug %] review view. In-progress drafts
+ link at the bottom of the bug review view. In-progress drafts
are shown in bold.
</p>
diff --git a/extensions/Splinter/web/splinter.css b/extensions/Splinter/web/splinter.css
index a4b4f0b6f..3f2eb84fe 100644
--- a/extensions/Splinter/web/splinter.css
+++ b/extensions/Splinter/web/splinter.css
@@ -34,6 +34,11 @@ textarea:focus {
margin-bottom: 1em;
}
+#attachObsolete {
+ font-weight: bold;
+ color: #c00000;
+}
+
.attachment-draft .attachment-id, .attachment-draft .attachment-desc {
font-weight: bold;
}
@@ -400,3 +405,11 @@ div.review-patch-comment-text {
padding-right: 5px;
font-family: monospace;
}
+
+.file-review-label {
+ font-size: 80%;
+}
+
+.file-reviewed-nav {
+ text-decoration: line-through;
+}
diff --git a/extensions/Splinter/web/splinter.js b/extensions/Splinter/web/splinter.js
index efcac8b6f..87a8b49d5 100644
--- a/extensions/Splinter/web/splinter.js
+++ b/extensions/Splinter/web/splinter.js
@@ -394,6 +394,7 @@ Splinter.Patch.File.prototype = {
this.filename = filename;
this.status = status;
this.hunks = hunks;
+ this.fileReviewed = false;
var l = 0;
var i;
@@ -1153,10 +1154,13 @@ Splinter.ReviewStorage.LocalReviewStorage.prototype = {
}
},
- saveDraft : function(bug, attachment, review) {
+ saveDraft : function(bug, attachment, review, extraProps) {
var propertyName = this._reviewPropertyName(bug, attachment);
-
- this._updateOrCreateReviewInfo(bug, attachment, { isDraft: true });
+ if (!extraProps) {
+ extraProps = {};
+ }
+ extraProps.isDraft = true;
+ this._updateOrCreateReviewInfo(bug, attachment, extraProps);
localStorage[propertyName] = "" + review;
},
@@ -1313,6 +1317,12 @@ Splinter.haveDraft = function () {
}
}
+ for (i = 0; i < Splinter.thePatch.files.length; i++) {
+ if (Splinter.thePatch.files[i].fileReviewed) {
+ return true;
+ }
+ }
+
if (Splinter.flagChanged == 1) {
return true;
}
@@ -1374,7 +1384,15 @@ Splinter.saveDraft = function () {
var draftSaved = false;
if (Splinter.haveDraft()) {
- Splinter.reviewStorage.saveDraft(Splinter.theBug, Splinter.theAttachment, Splinter.theReview);
+ var filesReviewed = {};
+ for (var i = 0; i < Splinter.thePatch.files.length; i++) {
+ var file = Splinter.thePatch.files[i];
+ if (file.fileReviewed) {
+ filesReviewed[file.filename] = true;
+ }
+ }
+ Splinter.reviewStorage.saveDraft(Splinter.theBug, Splinter.theAttachment, Splinter.theReview,
+ { 'filesReviewed' : filesReviewed });
draftSaved = true;
} else {
Splinter.reviewStorage.deleteDraft(Splinter.theBug, Splinter.theAttachment, Splinter.theReview);
@@ -1897,6 +1915,29 @@ Splinter.addPatchFile = function (file) {
fileLabelStatus.appendChild(document.createTextNode(statusString));
fileLabelStatus.appendTo(fileLabel);
+ var fileReviewed = new Element(document.createElement('span'));
+ Dom.addClass(fileReviewed, 'file-review');
+ Dom.setAttribute(fileReviewed, 'title', 'Indicates that a review has been completed for this file. ' +
+ 'This is for personal tracking purposes only and has no effect ' +
+ 'on the published review.');
+ fileReviewed.appendTo(fileLabel);
+
+ var fileReviewedInput = new Element(document.createElement('input'));
+ Dom.setAttribute(fileReviewedInput, 'type', 'checkbox');
+ Dom.setAttribute(fileReviewedInput, 'id', 'file-review-checkbox-' + encodeURIComponent(file.filename));
+ Dom.setAttribute(fileReviewedInput, 'onchange', "Splinter.toggleFileReviewed('" +
+ encodeURIComponent(file.filename) + "');");
+ if (file.fileReviewed) {
+ Dom.setAttribute(fileReviewedInput, 'checked', 'true');
+ }
+ fileReviewedInput.appendTo(fileReviewed);
+
+ var fileReviewedLabel = new Element(document.createElement('label'));
+ Dom.addClass(fileReviewedLabel, 'file-review-label')
+ Dom.setAttribute(fileReviewedLabel, 'for', 'file-review-checkbox-' + encodeURIComponent(file.filename));
+ fileReviewedLabel.appendChild(document.createTextNode(' Reviewed'));
+ fileReviewedLabel.appendTo(fileReviewed);
+
var lastHunk = file.hunks[file.hunks.length - 1];
var lastLine = Math.max(lastHunk.oldStart + lastHunk.oldCount - 1,
lastHunk.newStart + lastHunk.newCount - 1);
@@ -2079,7 +2120,7 @@ Splinter.toggleCollapsed = function (filename, display) {
var i;
for (i = 0; i < Splinter.thePatch.files.length; i++) {
var file = Splinter.thePatch.files[i];
- if ((filename && file.filename == filename) || !filename) {
+ if (!filename || filename == file.filename) {
var fileTableContainer = file.div.getElementsByClassName('file-table-container')[0];
var fileCollapseLink = file.div.getElementsByClassName('file-label-collapse')[0];
if (!display) {
@@ -2091,6 +2132,31 @@ Splinter.toggleCollapsed = function (filename, display) {
}
}
+Splinter.toggleFileReviewed = function (filename) {
+ var checkbox = Dom.get('file-review-checkbox-' + filename);
+ if (checkbox) {
+ filename = decodeURIComponent(filename);
+ for (var i = 0; i < Splinter.thePatch.files.length; i++) {
+ var file = Splinter.thePatch.files[i];
+ if (file.filename == filename) {
+ file.fileReviewed = checkbox.checked;
+
+ Splinter.saveDraft();
+ Splinter.queueUpdateHaveDraft();
+
+ // Strike through file names to show review was completed
+ var fileNavLink = Dom.get('switch-' + encodeURIComponent(filename));
+ if (file.fileReviewed) {
+ Dom.addClass(fileNavLink, 'file-reviewed-nav');
+ }
+ else {
+ Dom.removeClass(fileNavLink, 'file-reviewed-nav');
+ }
+ }
+ }
+ }
+}
+
Splinter.showPatchFile = function (file) {
Splinter.selectNavigationLink(file.filename);
Dom.setStyle('overview', 'display', 'none');
@@ -2208,7 +2274,7 @@ Splinter.start = function () {
}
}
- // We load the saved draft or create a new reeview *after* inserting the existing reviews
+ // We load the saved draft or create a new review *after* inserting the existing reviews
// so that the ordering comes out right.
if (Splinter.reviewStorage) {
@@ -2221,6 +2287,18 @@ Splinter.start = function () {
storedReviews[i].attachmentId == Splinter.theAttachment.id)
{
Dom.get("restoredLastModified").innerHTML = Splinter.Utils.formatDate(new Date(storedReviews[i].modificationTime));
+ // Restore file reviewed checkboxes
+ if (storedReviews[i].filesReviewed) {
+ for (var j = 0; j < Splinter.thePatch.files.length; j++) {
+ var file = Splinter.thePatch.files[j];
+ if (storedReviews[i].filesReviewed[file.filename]) {
+ file.fileReviewed = true;
+ // Strike through file names to show that review was completed
+ var fileNavLink = Dom.get('switch-' + encodeURIComponent(file.filename));
+ Dom.addClass(fileNavLink, 'file-reviewed-nav');
+ }
+ }
+ }
}
}
}
@@ -2434,7 +2512,7 @@ Splinter.init = function () {
}
Dom.get("bugId").innerHTML = Splinter.theBug.id;
- Dom.get("bugLink").setAttribute('href', Splinter.configBugUrl + "show_bug.cgi?id=" + Splinter.theBug.id);
+ Dom.get("bugLink").setAttribute('href', Splinter.configBugzillaUrl + "show_bug.cgi?id=" + Splinter.theBug.id);
Dom.get("bugShortDesc").innerHTML = YAHOO.lang.escapeHTML(Splinter.theBug.shortDesc);
Dom.get("bugReporter").appendChild(document.createTextNode(Splinter.theBug.getReporter()));
Dom.get("bugCreationDate").innerHTML = Splinter.Utils.formatDate(Splinter.theBug.creationDate);
@@ -2457,11 +2535,14 @@ Splinter.init = function () {
} else {
Dom.get("attachId").innerHTML = Splinter.theAttachment.id;
- Dom.get("attachLink").setAttribute('href', Splinter.configBugUrl + "attachment.cgi?id=" + Splinter.theAttachment.id);
+ Dom.get("attachLink").setAttribute('href', Splinter.configBugzillaUrl + "attachment.cgi?id=" + Splinter.theAttachment.id);
Dom.get("attachDesc").innerHTML = YAHOO.lang.escapeHTML(Splinter.theAttachment.description);
Dom.get("attachCreator").appendChild(document.createTextNode(Splinter.Bug._formatWho(Splinter.theAttachment.whoName,
Splinter.theAttachment.whoEmail)));
Dom.get("attachDate").innerHTML = Splinter.Utils.formatDate(Splinter.theAttachment.date);
+ if (Splinter.theAttachment.isObsolete) {
+ Dom.get("attachObsolete").innerHTML = 'OBSOLETE';
+ }
Dom.setStyle('attachInfo', 'display', 'block');
Dom.setStyle('quickHelpShow', 'display', 'block');
diff --git a/extensions/TagNewUsers/Extension.pm b/extensions/TagNewUsers/Extension.pm
index 382a3c3d1..d71c4ea20 100644
--- a/extensions/TagNewUsers/Extension.pm
+++ b/extensions/TagNewUsers/Extension.pm
@@ -26,6 +26,7 @@ use Bugzilla::Field;
use Bugzilla::User;
use Bugzilla::Install::Util qw(indicate_progress);
use Date::Parse;
+use Scalar::Util qw(blessed);
# users younger than PROFILE_AGE days will be tagged as new
use constant PROFILE_AGE => 60;
@@ -223,4 +224,19 @@ sub _user_is_new {
|| ($user->{creation_age} <= PROFILE_AGE);
}
+sub webservice_user_get {
+ my ($self, $args) = @_;
+ my ($webservice, $params, $users) = @$args{qw(webservice params users)};
+
+ foreach my $user (@$users) {
+ # Most of the time the hash values are XMLRPC::Data objects
+ my $email = blessed $user->{'email'} ? $user->{'email'}->value : $user->{'email'};
+ if ($email) {
+ my $user_obj = Bugzilla::User->new({ name => $email });
+ $user->{'is_new'}
+ = $webservice->type('boolean', $self->_user_is_new($user_obj) ? 1 : 0);
+ }
+ }
+}
+
__PACKAGE__->NAME;
diff --git a/extensions/TagNewUsers/template/en/default/hook/bug/comments-user.html.tmpl b/extensions/TagNewUsers/template/en/default/hook/bug/comments-user.html.tmpl
index 316d381bb..274d26435 100644
--- a/extensions/TagNewUsers/template/en/default/hook/bug/comments-user.html.tmpl
+++ b/extensions/TagNewUsers/template/en/default/hook/bug/comments-user.html.tmpl
@@ -23,11 +23,11 @@
<span
class="new_user"
title="
-[%- comment.author.comment_count FILTER html %] comment[% "s" IF comment.author.comment_count != 1 -%]
+[%- comment.author.comment_count %] comment[% "s" IF comment.author.comment_count != 1 -%]
, created [%
IF comment.author.creation_age == 0 %]today[%
ELSIF comment.author.creation_age > 365 %]more than a year ago[%
-ELSE %][% comment.author.creation_age FILTER html %] day[% "s" IF comment.author.creation_age != 1 %] ago[% END %]."
+ELSE %][% comment.author.creation_age %] day[% "s" IF comment.author.creation_age != 1 %] ago[% END %]."
>
(New to [% terms.Bugzilla %])
</span>
diff --git a/extensions/TypeSniffer/Extension.pm b/extensions/TypeSniffer/Extension.pm
index ead4f40cf..fcd4f7dd6 100644
--- a/extensions/TypeSniffer/Extension.pm
+++ b/extensions/TypeSniffer/Extension.pm
@@ -42,28 +42,12 @@ sub attachment_process_data {
if ($params->{'contenttypemethod'} eq 'autodetect' &&
$attributes->{'mimetype'} eq 'application/octet-stream')
{
- # data attribute can be either scalar data or filehandle
- # bugzilla.org/docs/3.6/en/html/api/Bugzilla/Attachment.html#create
- my $fh = $attributes->{'data'};
+ # data is either a filehandle, or the data itself
+ my $fh = ${$args->{'data'}};
if (!ref($fh)) {
- my $data = $attributes->{'data'};
- $fh = new IO::Scalar \$data;
+ $fh = IO::Scalar->new(\$fh);
}
- else {
- # CGI.pm sends us an Fh that isn't actually an IO::Handle, but
- # has a method for getting an actual handle out of it.
- if (!$fh->isa('IO::Handle')) {
- $fh = $fh->handle;
- # ->handle returns an literal IO::Handle, even though the
- # underlying object is a file. So we rebless it to be a proper
- # IO::File object so that we can call ->seek on it and so on.
- # Just in case CGI.pm fixes this some day, we check ->isa first.
- if (!$fh->isa('IO::File')) {
- bless $fh, 'IO::File';
- }
- }
- }
-
+
my $mimetype = mimetype($fh);
if ($mimetype) {
$attributes->{'mimetype'} = $mimetype;
diff --git a/extensions/Voting/Extension.pm b/extensions/Voting/Extension.pm
index 6a90176ec..44344d7f5 100644
--- a/extensions/Voting/Extension.pm
+++ b/extensions/Voting/Extension.pm
@@ -48,24 +48,13 @@ use constant DEFAULT_VOTES_PER_BUG => 1;
use constant CMT_POPULAR_VOTES => 3;
use constant REL_VOTER => 4;
-################
-# Installation #
-################
-
BEGIN {
- *Bugzilla::Bug::votes = \&votes;
+ *Bugzilla::Bug::user_votes = \&_bug_user_votes;
}
-sub votes {
- my $self = shift;
- my $dbh = Bugzilla->dbh;
-
- return $self->{votes} if exists $self->{votes};
-
- $self->{votes} = $dbh->selectrow_array('SELECT votes FROM bugs WHERE bug_id = ?',
- undef, $self->id);
- return $self->{votes};
-}
+################
+# Installation #
+################
sub db_schema_abstract_schema {
my ($self, $args) = @_;
@@ -123,6 +112,15 @@ sub install_update_db {
# Objects #
###########
+sub _bug_user_votes {
+ my ($self) = @_;
+ return $self->{'user_votes'} if exists $self->{'user_votes'};
+ $self->{'user_votes'} = Bugzilla->dbh->selectrow_array(
+ "SELECT vote_count FROM votes WHERE bug_id = ? AND who = ?",
+ undef, $self->id, Bugzilla->user->id);
+ return $self->{'user_votes'};
+}
+
sub object_columns {
my ($self, $args) = @_;
my ($class, $columns) = @$args{qw(class columns)};
@@ -678,7 +676,7 @@ sub _modify_bug_votes {
}
}
- $changes->{'_too_many_votes'} = \@toomanyvotes_list;
+ $changes->{'too_many_votes'} = \@toomanyvotes_list;
# 2. too many total votes for a single user.
# This part doesn't work in the general case because _remove_votes
@@ -725,7 +723,7 @@ sub _modify_bug_votes {
}
}
- $changes->{'_too_many_total_votes'} = \@toomanytotalvotes_list;
+ $changes->{'too_many_total_votes'} = \@toomanytotalvotes_list;
# 3. enough votes to confirm
my $bug_list = $dbh->selectcol_arrayref(
@@ -738,7 +736,7 @@ sub _modify_bug_votes {
my $confirmed = _confirm_if_vote_confirmed($bug_id);
push (@updated_bugs, $bug_id) if $confirmed;
}
- $changes->{'_confirmed_bugs'} = \@updated_bugs;
+ $changes->{'confirmed_bugs'} = \@updated_bugs;
# Now that changes are done, we can send emails to voters.
foreach my $msg (@msgs) {
@@ -748,7 +746,7 @@ sub _modify_bug_votes {
foreach my $bug_id (@updated_bugs) {
my $sent_bugmail = Bugzilla::BugMail::Send(
$bug_id, { changer => Bugzilla->user });
- $changes->{'_confirmed_bugs_sent_bugmail'}->{$bug_id} = $sent_bugmail;
+ $changes->{'confirmed_bugs_sent_bugmail'}->{$bug_id} = $sent_bugmail;
}
}
@@ -821,7 +819,7 @@ sub _remove_votes {
};
my $voter = new Bugzilla::User($userid);
- my $template = Bugzilla->template_inner($voter->setting('lang'));
+ my $template = Bugzilla->template_inner($voter->settings->{'lang'}->{'value'});
my $msg;
$template->process("voting/votes-removed.txt.tmpl", $vars, \$msg);
diff --git a/extensions/Voting/template/en/default/hook/admin/products/updated-changes.html.tmpl b/extensions/Voting/template/en/default/hook/admin/products/updated-changes.html.tmpl
index 15fb1efe0..af2b1c102 100644
--- a/extensions/Voting/template/en/default/hook/admin/products/updated-changes.html.tmpl
+++ b/extensions/Voting/template/en/default/hook/admin/products/updated-changes.html.tmpl
@@ -56,8 +56,8 @@
<p>Checking existing votes in this product for anybody who now
has too many votes for [% terms.abug %]...<br>
- [% IF changes._too_many_votes.size %]
- [% FOREACH detail = changes._too_many_votes %]
+ [% IF changes.too_many_votes.size %]
+ [% FOREACH detail = changes.too_many_votes %]
&rarr;removed votes for [% terms.bug %] <a href="show_bug.cgi?id=
[%- detail.id FILTER uri %]">
[%- detail.id FILTER html %]</a> from [% detail.name FILTER html %]<br>
@@ -69,8 +69,8 @@
<p>Checking existing votes in this product for anybody
who now has too many total votes...<br>
- [% IF changes._too_many_total_votes.size %]
- [% FOREACH detail = changes._too_many_total_votes %]
+ [% IF changes.too_many_total_votes.size %]
+ [% FOREACH detail = changes.too_many_total_votes %]
&rarr;removed votes for [% terms.bug %] <a href="show_bug.cgi?id=
[%- detail.id FILTER uri %]">
[%- detail.id FILTER html %]</a> from [% detail.name FILTER html %]<br>
@@ -82,15 +82,15 @@
<p>Checking unconfirmed [% terms.bugs %] in this product for any which now have
sufficient votes...<br>
- [% IF changes._confirmed_bugs.size %]
- [% FOREACH id = changes._confirmed_bugs %]
+ [% IF changes.confirmed_bugs.size %]
+ [% FOREACH id = changes.confirmed_bugs %]
[%# This is INCLUDED instead of PROCESSED to avoid variables getting
overwritten, which happens otherwise %]
[% INCLUDE bug/process/results.html.tmpl
type = 'votes'
header_done = 1
- sent_bugmail = changes._confirmed_bugs_sent_bugmail.$id
+ sent_bugmail = changes.confirmed_bugs_sent_bugmail.$id
id = id
%]
[% END %]
diff --git a/extensions/Voting/template/en/default/hook/bug/edit-after_importance.html.tmpl b/extensions/Voting/template/en/default/hook/bug/edit-after_importance.html.tmpl
index f73ffaebd..b57a5cb27 100644
--- a/extensions/Voting/template/en/default/hook/bug/edit-after_importance.html.tmpl
+++ b/extensions/Voting/template/en/default/hook/bug/edit-after_importance.html.tmpl
@@ -29,6 +29,9 @@
[% ELSE %]
votes
[% END %]</a>
+ [% IF bug.user_votes %]
+ including you
+ [% END %]
[% END %]
(<a href="page.cgi?id=voting/user.html&amp;bug_id=
[%- bug.id FILTER uri %]#vote_
diff --git a/extensions/Voting/template/en/default/pages/voting/user.html.tmpl b/extensions/Voting/template/en/default/pages/voting/user.html.tmpl
index 61eaf8491..169e9995d 100644
--- a/extensions/Voting/template/en/default/pages/voting/user.html.tmpl
+++ b/extensions/Voting/template/en/default/pages/voting/user.html.tmpl
@@ -111,15 +111,8 @@
[% FOREACH bug = product.bugs %]
<tr [% IF bug.id == this_bug.id && canedit %]
class="bz_bug_being_voted_on" [% END %]>
- <td>
- [% IF bug.id == this_bug.id && canedit %]
- [% IF product.onevoteonly %]
- Vote For This [% terms.Bug %] &rarr;
- [% ELSE %]
- Enter Votes Here &rarr;
- [% END %]
- [%- END %]
- </td>
+ <td>[% IF bug.id == this_bug.id && canedit %]Enter New Vote here &rarr;
+ [%- END %]</td>
<td align="right"><a name="vote_[% bug.id FILTER html %]">
[% IF canedit %]
[% IF product.onevoteonly %]