diff options
Diffstat (limited to 'extensions')
134 files changed, 1024 insertions, 2845 deletions
diff --git a/extensions/BMO/lib/Data.pm b/extensions/BMO/lib/Data.pm index 30a32c95e..349f88093 100644 --- a/extensions/BMO/lib/Data.pm +++ b/extensions/BMO/lib/Data.pm @@ -58,7 +58,7 @@ our %autodetect_attach_urls = ( title => 'MozReview', regex => $mozreview_url_re, content_type => 'text/x-review-board-request', - can_review => 1, + can_review => 0, }, Phabricator => { title => 'Phabricator', @@ -114,6 +114,7 @@ tie(%$cf_visible_in_products, "Tie::IxHash", "External Software Affecting Firefox" => [], "Firefox" => [], "Firefox for Android" => [], + "GeckoView" => [], "JSS" => [], "MailNews Core" => [], "Mozilla Labs" => [], @@ -140,6 +141,7 @@ tie(%$cf_visible_in_products, "Tie::IxHash", "Data & BI Services Team" => [], "Data Compliance" => [], "Developer Engagement" => [], + "Firefox" => ["Security: Review Requests"], "Infrastructure & Operations" => [], "Marketing" => [], "mozilla.org" => ["Security Assurance: Review Request"], @@ -162,24 +164,27 @@ tie(%$cf_visible_in_products, "Tie::IxHash", "Firefox for Android" => [], "Firefox for iOS" => [], "Firefox" => [], + "GeckoView" => [], "Hello (Loop)" => [], "Cloud Services" => [], "Tech Evangelism" => [], "Toolkit" => [], }, qr/^cf_has_regression_range$/ => { - "Core" => [], + "Core" => [], "Firefox for Android" => [], "Firefox for iOS" => [], - "Firefox" => [], - "Toolkit" => [], + "Firefox" => [], + "GeckoView" => [], + "Toolkit" => [], }, qr/^cf_has_str$/ => { "Core" => [], "Firefox for Android" => [], "Firefox for iOS" => [], - "Firefox" => [], - "Toolkit" => [], + "Firefox" => [], + "GeckoView" => [], + "Toolkit" => [], }, qr/^cf_cab_review$/ => { "Infrastructure & Operations Graveyard" => [], diff --git a/extensions/BMO/lib/Reports/ReleaseTracking.pm b/extensions/BMO/lib/Reports/ReleaseTracking.pm index 42ef24b47..9fba1e14b 100644 --- a/extensions/BMO/lib/Reports/ReleaseTracking.pm +++ b/extensions/BMO/lib/Reports/ReleaseTracking.pm @@ -421,16 +421,6 @@ sub report { $query .= join("\nAND ", @where); - if ($input->{debug}) { - print "Content-Type: text/plain\n\n"; - $query =~ s/\?/\000/g; - foreach my $param (@params) { - $query =~ s/\000/'$param'/; - } - print "$query\n"; - exit; - } - my $bugs = $dbh->selectcol_arrayref($query, undef, @params); push @$bugs, 0 unless @$bugs; diff --git a/extensions/BMO/template/en/default/bug/create/comment-finance.txt.tmpl b/extensions/BMO/template/en/default/bug/create/comment-finance.txt.tmpl index f0427b4c5..c55ea1d96 100644 --- a/extensions/BMO/template/en/default/bug/create/comment-finance.txt.tmpl +++ b/extensions/BMO/template/en/default/bug/create/comment-finance.txt.tmpl @@ -14,10 +14,10 @@ Summary: [% cgi.param('short_desc') %] Priority to your Team: [% cgi.param('team_priority') %] Timeframe for Signature: [% cgi.param('signature_time') %] -Name of Other Party: +Name of Other Party: [%+ cgi.param('other_party') %] -Business Objective: +Business Objective: [%+ cgi.param('business_obj') %] What is this purchase?: diff --git a/extensions/BMO/template/en/default/bug/create/comment-mozlist.txt.tmpl b/extensions/BMO/template/en/default/bug/create/comment-mozlist.txt.tmpl index c62461d42..7c14ec95f 100644 --- a/extensions/BMO/template/en/default/bug/create/comment-mozlist.txt.tmpl +++ b/extensions/BMO/template/en/default/bug/create/comment-mozlist.txt.tmpl @@ -24,7 +24,7 @@ # enter_bug.cgi) can be access via Bugzilla.cgi.param. It can be used to # pull out various custom fields and format an initial Description entry # from them. - #%] + #%] [% USE Bugzilla %] [% cgi = Bugzilla.cgi %] List Name: [% cgi.param("listName") %] diff --git a/extensions/BMO/template/en/default/bug/create/create-doc.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-doc.html.tmpl index becbb2b56..9ff4ef2e3 100644 --- a/extensions/BMO/template/en/default/bug/create/create-doc.html.tmpl +++ b/extensions/BMO/template/en/default/bug/create/create-doc.html.tmpl @@ -106,10 +106,10 @@ function validateAndSubmit() { <td colspan="3"> <div id="possible_duplicates"></div> <script> - var dt_columns = [ + var dt_columns = [ { key: "id", label: "[% field_descs.bug_id FILTER js %]", formatter: YAHOO.bugzilla.dupTable.formatBugLink }, - { key: "summary", + { key: "summary", label: "[% field_descs.short_desc FILTER js %]", formatter: "text" }, { key: "status", diff --git a/extensions/BMO/template/en/default/bug/create/create-finance.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-finance.html.tmpl index 8b2fd63da..434c82fa3 100644 --- a/extensions/BMO/template/en/default/bug/create/create-finance.html.tmpl +++ b/extensions/BMO/template/en/default/bug/create/create-finance.html.tmpl @@ -181,7 +181,7 @@ </th> <td> <i> - Describe your request, what items are we purchasing, including number of + Describe your request, what items are we purchasing, including number of units if available.<br>Also provide context and background. Enter No if not a purchase order.</i><br> <textarea name="what_purchase" id="what_purchase" rows="5" cols="40"></textarea> @@ -235,7 +235,7 @@ <label for="attachment">Attachment:</label> </th> <td> - <i>Upload document that needs to be signed. If this is a Purchase Request form,<br> + <i>Upload document that needs to be signed. If this is a Purchase Request form,<br> also upload any supporting document such as draft SOW, quote, order form, etc.</i> <div> <input type="file" id="attachment" name="data" size="50"> 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 841477099..8c54bc803 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 @@ -55,7 +55,7 @@ <div id="message"> <b>Note:</b> - You must use <a href="https://mozilla.service-now.com/"><b>Service Now</b></a> + You must use <a href="https://mozilla.service-now.com/"><b>Service Now</b></a> to request a distribution list or a standard mailing list. </div> <br> @@ -79,7 +79,7 @@ <span class="mandatory" title="Required">*</span> List Name: </th> <td> - The desired name for the newsgroup. Should start with 'mozilla.' and fit somewhere + The desired name for the newsgroup. Should start with 'mozilla.' and fit somewhere in the hierarchy described <a href="https://www.mozilla.org/about/forums/">here</a>.<br> <input name="listName" id="listName" size="60" value="[% listName FILTER html %]"> </td> diff --git a/extensions/BMO/template/en/default/bug/create/create-recoverykey.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-recoverykey.html.tmpl index ffe9b3482..3ede350a2 100644 --- a/extensions/BMO/template/en/default/bug/create/create-recoverykey.html.tmpl +++ b/extensions/BMO/template/en/default/bug/create/create-recoverykey.html.tmpl @@ -1,33 +1,33 @@ -[%# 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 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 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): + # Contributor(s): # David Lawrence <dkl@mozilla.com> - #%] - -[% PROCESS global/variables.none.tmpl %] - -[% PROCESS global/header.html.tmpl - title = "Mozilla Corporation/Foundation Encryption Recovery Key" + #%] + +[% PROCESS global/variables.none.tmpl %] + +[% PROCESS global/header.html.tmpl + title = "Mozilla Corporation/Foundation Encryption Recovery Key" %] - + <p>Please complete the following information as you are encrypting your laptop.</p> <ul> - <li>The Recovery Key will be displayed during the encryption process + <li>The Recovery Key will be displayed during the encryption process (<a href="https://mana.mozilla.org/wiki/display/INFRASEC/Desktop+Security#DesktopSecurity-DiskencryptionFileVault">more info</a>) </li> <li>The asset tag number is located on a sticker typically on the bottom of the device.</li> @@ -67,4 +67,4 @@ </table> </form> -[% PROCESS global/footer.html.tmpl %] +[% PROCESS global/footer.html.tmpl %] diff --git a/extensions/BMO/template/en/default/bug/create/create-trademark.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-trademark.html.tmpl index 90da895b2..0a7629a88 100644 --- a/extensions/BMO/template/en/default/bug/create/create-trademark.html.tmpl +++ b/extensions/BMO/template/en/default/bug/create/create-trademark.html.tmpl @@ -1,36 +1,36 @@ -[%# 1.0@bugzilla.org %] -[%# 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 Bugzilla Bug Tracking System. - # - # The Initial Developer of the Original Code is Netscape Communications - # Corporation. Portions created by Netscape are - # Copyright (C) 1998 Netscape Communications Corporation. All - # Rights Reserved. - # - # Contributor(s): Gervase Markham <gerv@gerv.net> +[%# 1.0@bugzilla.org %] +[%# 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 Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Netscape Communications + # Corporation. Portions created by Netscape are + # Copyright (C) 1998 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): Gervase Markham <gerv@gerv.net> # Ville Skyttä <ville.skytta@iki.fi> # John Hoogstrate <hoogstrate@zeelandnet.nl> - #%] - -[% PROCESS global/variables.none.tmpl %] - -[% PROCESS global/header.html.tmpl - title = "Trademark Usage Requests" + #%] + +[% PROCESS global/variables.none.tmpl %] + +[% PROCESS global/header.html.tmpl + title = "Trademark Usage Requests" %] - -[% USE Bugzilla %] + +[% USE Bugzilla %] <p> - If, after reading + If, after reading <a href="https://www.mozilla.org/foundation/trademarks/">the trademark policy documents</a>, you know you need permission to use a certain trademark, this is the place to be. @@ -39,7 +39,7 @@ <p><strong>Please use this form for trademark requests only!</strong></p> <form method="post" action="post_bug.cgi" id="tmRequestForm"> - + <input type="hidden" name="product" value="Marketing"> <input type="hidden" name="component" value="Trademark Permissions"> <input type="hidden" name="bug_severity" value="enhancement"> @@ -79,9 +79,9 @@ <input type="submit" id="commit" value="Submit Request"> </form> -<p>Thanks for contacting us. +<p>Thanks for contacting us. You will be notified by email of any progress made in resolving your request. </p> -[% PROCESS global/footer.html.tmpl %] +[% PROCESS global/footer.html.tmpl %] diff --git a/extensions/BMO/template/en/default/bug/create/custom_forms.none.tmpl b/extensions/BMO/template/en/default/bug/create/custom_forms.none.tmpl index 7b588f765..0d37a1386 100644 --- a/extensions/BMO/template/en/default/bug/create/custom_forms.none.tmpl +++ b/extensions/BMO/template/en/default/bug/create/custom_forms.none.tmpl @@ -168,12 +168,6 @@ custom_forms = { title => "Intern Requests", }, ] - "Mozilla Labs" => [ - { - link => "https://github.com/mozilla/personas-plus/issues", - title => "Report issue with Personas Plus on Github" - } - ], "Legal" => [ { title => 'Mozilla Foundation Vendor Request', diff --git a/extensions/BMO/template/en/default/email/bugmail.html.tmpl b/extensions/BMO/template/en/default/email/bugmail.html.tmpl index 0b08e4a86..7f2754fdc 100644 --- a/extensions/BMO/template/en/default/email/bugmail.html.tmpl +++ b/extensions/BMO/template/en/default/email/bugmail.html.tmpl @@ -111,7 +111,7 @@ [% END %] [% END %] </ul> - Configure your email settings at + Configure your email settings at <a href="[% urlbase FILTER none %]userprefs.cgi?tab=email">[% urlbase FILTER none %]userprefs.cgi?tab=email</a>. </div> 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 dfa9b5af4..74c9f7b0d 100644 --- a/extensions/BMO/template/en/default/global/choose-product.html.tmpl +++ b/extensions/BMO/template/en/default/global/choose-product.html.tmpl @@ -36,7 +36,10 @@ "extensions/BMO/web/styles/choose_product.css", "extensions/ProdCompSearch/web/styles/prod_comp_search.css", ]; - javascript_urls = [ "extensions/ProdCompSearch/web/js/prod_comp_search.js" ]; + javascript_urls = [ + "extensions/BMO/web/js/new-bug-frequent-comp.js", + "extensions/ProdCompSearch/web/js/prod_comp_search.js", + ]; cgi = Bugzilla.cgi; classification = cgi.param('classification'); @@ -68,6 +71,13 @@ %] </div> +[% IF NOT is_describe %] +<section id="frequent-components" hidden> + <h2>Choose from your most-used components</h2> + <div class="results"></div> +</section> +[% END %] + <section id="product-list"> <h2>or choose from the following selections</h2> @@ -103,10 +113,18 @@ icon="component.png" %] [% INCLUDE easyproduct + name="GeckoView" + icon="firefox_android.png" + %] + [% INCLUDE easyproduct name="Mozilla Localizations" icon="localization.png" %] [% INCLUDE easyproduct + name="Data Platform and Tools" + icon="telemetry.png" + %] + [% INCLUDE easyproduct name="Thunderbird" icon="thunderbird.png" %] @@ -114,10 +132,6 @@ name="SeaMonkey" icon="seamonkey.png" %] - [% INCLUDE easyproduct - name="Data Platform and Tools" - icon="telemetry.png" - %] <section class="product other"> <h3> <a href="[% target FILTER uri %]?full=1 diff --git a/extensions/BMO/template/en/default/hook/bug/field-help-end.none.tmpl b/extensions/BMO/template/en/default/hook/bug/field-help-end.none.tmpl index dda75a9c6..c70b35825 100644 --- a/extensions/BMO/template/en/default/hook/bug/field-help-end.none.tmpl +++ b/extensions/BMO/template/en/default/hook/bug/field-help-end.none.tmpl @@ -20,13 +20,13 @@ [% USE Bugzilla %] [% IF Bugzilla.request_cache.bmo_fields_page %] - [% + [% vars.help_html.priority = "This field describes the importance and order in which $terms.abug should be fixed compared to other ${terms.bugs}. This field is utilized by the programmers/engineers to prioritize their work to be done where P1 is considered the highest and P5 is the lowest." - + vars.help_html.bug_severity = "This field describes the impact of ${terms.abug}. <table> @@ -60,9 +60,9 @@ <th>enhancement</th> <td>Request for enhancement</td> </table>" - - vars.help_html.rep_platform = - "This is the hardware platform against which the $terms.bug was reported. + + vars.help_html.rep_platform = + "This is the hardware platform against which the $terms.bug was reported. Legal platforms include: <ul> <li>All (happens on all platforms; cross-platform ${terms.bug})</li> @@ -71,10 +71,10 @@ </ul> <b>Note:</b> When searching, selecting the option <em>All</em> does not - select $terms.bugs assigned against any platform. It merely selects - $terms.bugs that are marked as occurring on all platforms, i.e. are + select $terms.bugs assigned against any platform. It merely selects + $terms.bugs that are marked as occurring on all platforms, i.e. are designated <em>All</em>.", - + vars.help_html.op_sys = "This is the operating system against which the $terms.bug was reported. Legal operating systems include: @@ -86,10 +86,10 @@ </ul> Sometimes the operating system implies the platform, but not always. For example, Linux can run on x86_64, ARM, and others.", - + vars.help_html.assigned_to = "This is the person in charge of resolving the ${terms.bug}. Every time - this field changes, the status changes to + this field changes, the status changes to <b>NEW</b> to make it easy to see which new $terms.bugs have appeared on a person's list.</p>", %] diff --git a/extensions/BMO/template/en/default/hook/bug/show-header-end.html.tmpl b/extensions/BMO/template/en/default/hook/bug/show-header-end.html.tmpl index c49d06b73..9458fd375 100644 --- a/extensions/BMO/template/en/default/hook/bug/show-header-end.html.tmpl +++ b/extensions/BMO/template/en/default/hook/bug/show-header-end.html.tmpl @@ -18,7 +18,7 @@ [% title = title _ "($filtered_alias) " %] [% END %] [% title = title _ filtered_desc %] -[% javascript = javascript _ +[% javascript = javascript _ "document.title = document.title.replace(/^" _ terms.Bug _ " /, '');" %] [% js_bug_id = bug.bug_id FILTER js %] diff --git a/extensions/BMO/template/en/default/hook/flag/type_comment-form.html.tmpl b/extensions/BMO/template/en/default/hook/flag/type_comment-form.html.tmpl new file mode 100644 index 000000000..7703bed74 --- /dev/null +++ b/extensions/BMO/template/en/default/hook/flag/type_comment-form.html.tmpl @@ -0,0 +1,202 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +<template class="approval-request" data-flags="approval‑mozilla‑beta approval‑mozilla‑release"> + <fieldset> + <legend>Beta/Release Uplift Approval Request</legend> + <table> + <tr> + <th id="_ar_beta_i1_label">Feature/[% terms.Bug %] causing the regression</th> + <td><input type="text" placeholder="[% terms.Bug %] ID" aria-labelledby="_ar_beta_i1_label" data-type="b[% %]ug"></td> + </tr> + <tr> + <th id="_ar_beta_i2_label">User impact if declined</th> + <td><textarea aria-labelledby="_ar_beta_i2_label"></textarea></td> + </tr> + <tr> + <th id="_ar_beta_i3_label">Is this code covered by automated tests?</th> + <td> + <div role="radiogroup" class="buttons toggle" aria-labelledby="_ar_beta_i3_label"> + <div class="item"><input id="_ar_beta_i3_r1" type="radio" name="_ar_beta_i3_radio" value="Yes"><label for="_ar_beta_i3_r1">Yes</label></div> + <div class="item"><input id="_ar_beta_i3_r2" type="radio" name="_ar_beta_i3_radio" value="No"><label for="_ar_beta_i3_r2">No</label></div> + <div class="item"><input id="_ar_beta_i3_r3" type="radio" name="_ar_beta_i3_radio" value="Unknown"><label for="_ar_beta_i3_r3">Unknown</label></div> + </div> + </td> + </tr> + <tr> + <th id="_ar_beta_i4_label">Has the fix been verified in Nightly?</th> + <td> + <div role="radiogroup" class="buttons toggle" aria-labelledby="_ar_beta_i4_label"> + <div class="item"><input id="_ar_beta_i4_r1" type="radio" name="_ar_beta_i4_radio" value="Yes"><label for="_ar_beta_i4_r1">Yes</label></div> + <div class="item"><input id="_ar_beta_i4_r2" type="radio" name="_ar_beta_i4_radio" value="No"><label for="_ar_beta_i4_r2">No</label></div> + </div> + </td> + </tr> + <tr> + <th id="_ar_beta_i5_label">Needs manual test from QE?</th> + <td> + <div role="radiogroup" class="buttons toggle" aria-labelledby="_ar_beta_i5_label"> + <div class="item"><input id="_ar_beta_i5_r1" type="radio" name="_ar_beta_i5_radio" value="Yes"><label for="_ar_beta_i5_r1">Yes</label></div> + <div class="item"><input id="_ar_beta_i5_r2" type="radio" name="_ar_beta_i5_radio" value="No"><label for="_ar_beta_i5_r2">No</label></div> + </div> + </td> + </tr> + <tr> + <th id="_ar_beta_i6_label">If yes, steps to reproduce</th> + <td><textarea aria-labelledby="_ar_beta_i6_label"></textarea></td> + </tr> + <tr> + <th id="_ar_beta_i7_label">List of other uplifts needed</th> + <td><input type="text" placeholder="[% terms.Bug %] IDs" aria-labelledby="_ar_beta_i7_label" data-type="b[% %]ugs"></td> + </tr> + <tr> + <th id="_ar_beta_i8_label">Risk to taking this patch</th> + <td> + <div role="radiogroup" class="buttons toggle" aria-labelledby="_ar_beta_i8_label"> + <div class="item"><input id="_ar_beta_i8_r1" type="radio" name="_ar_beta_i8_radio" value="Low"><label for="_ar_beta_i8_r1">Low</label></div> + <div class="item"><input id="_ar_beta_i8_r2" type="radio" name="_ar_beta_i8_radio" value="Medium"><label for="_ar_beta_i8_r2">Medium</label></div> + <div class="item"><input id="_ar_beta_i8_r3" type="radio" name="_ar_beta_i8_radio" value="High"><label for="_ar_beta_i8_r3">High</label></div> + </div> + </td> + </tr> + <tr> + <th id="_ar_beta_i9_label">Why is the change risky/not risky?<br>(and alternatives if risky)</th> + <td><textarea aria-labelledby="_ar_beta_i9_label"></textarea></td> + </tr> + <tr> + <th id="_ar_beta_i10_label">String changes made/needed</th> + <td><input type="text" class="long" aria-labelledby="_ar_beta_i10_label"></td> + </tr> + </table> + </fieldset> +</template> + +<template class="approval-request" data-flags="approval‑mozilla‑esr*"> + <fieldset> + <legend>ESR Uplift Approval Request</legend> + <table> + <tr> + <th id="_ar_esr_i1_label">If this is not a sec:{high,crit} [% terms.bug %], please state case for ESR consideration</th> + <td><textarea aria-labelledby="_ar_esr_i1_label"></textarea></td> + </tr> + <tr> + <th id="_ar_esr_i2_label">User impact if declined</th> + <td><textarea aria-labelledby="_ar_esr_i2_label"></textarea></td> + </tr> + <tr> + <th id="_ar_esr_i3_label">Fix Landed on Version</th> + <td><input type="text" aria-labelledby="_ar_esr_i3_label"></td> + </tr> + <tr> + <th id="_ar_esr_i4_label">Risk to taking this patch</th> + <td> + <div role="radiogroup" class="buttons toggle" aria-labelledby="_ar_esr_i4_label"> + <div class="item"><input id="_ar_esr_i4_r1" type="radio" name="_ar_esr_i4_radio" value="Low"><label for="_ar_esr_i4_r1">Low</label></div> + <div class="item"><input id="_ar_esr_i4_r2" type="radio" name="_ar_esr_i4_radio" value="Medium"><label for="_ar_esr_i4_r2">Medium</label></div> + <div class="item"><input id="_ar_esr_i4_r3" type="radio" name="_ar_esr_i4_radio" value="High"><label for="_ar_esr_i4_r3">High</label></div> + </div> + </td> + </tr> + <tr> + <th id="_ar_esr_i5_label">Why is the change risky/not risky?<br>(and alternatives if risky)</th> + <td><textarea aria-labelledby="_ar_esr_i5_label"></textarea></td> + </tr> + <tr> + <th id="_ar_esr_i6_label">String or UUID changes made by this patch</th> + <td><input type="text" class="long" aria-labelledby="_ar_esr_i6_label"></td> + </tr> + </table> + <p>See <a href="https://wiki.mozilla.org/Release_Management/ESR_Landing_Process" target="_blank">ESR Landing Process</a> for more info.</p> + </fieldset> +</template> + +<template class="approval-request" data-flags="approval‑mozilla‑geckoview*"> + <fieldset> + <legend>GeckoView Uplift Approval Request</legend> + <table> + <tr> + <th id="_ar_gkv_i1_label">If this is not a sec:{high,crit} [% terms.bug %], please state case for consideration</th> + <td><textarea aria-labelledby="_ar_gkv_i1_label"></textarea></td> + </tr> + <tr> + <th id="_ar_gkv_i2_label">User impact if declined</th> + <td><textarea aria-labelledby="_ar_gkv_i2_label"></textarea></td> + </tr> + <tr> + <th id="_ar_gkv_i3_label">Fix Landed on Version</th> + <td><input type="text" aria-labelledby="_ar_gkv_i3_label"></td> + </tr> + <tr> + <th id="_ar_gkv_i4_label">Risk to taking this patch</th> + <td> + <div role="radiogroup" class="buttons toggle" aria-labelledby="_ar_gkv_i4_label"> + <div class="item"><input id="_ar_gkv_i4_r1" type="radio" name="_ar_gkv_i4_radio" value="Low"><label for="_ar_gkv_i4_r1">Low</label></div> + <div class="item"><input id="_ar_gkv_i4_r2" type="radio" name="_ar_gkv_i4_radio" value="Medium"><label for="_ar_gkv_i4_r2">Medium</label></div> + <div class="item"><input id="_ar_gkv_i4_r3" type="radio" name="_ar_gkv_i4_radio" value="High"><label for="_ar_gkv_i4_r3">High</label></div> + </div> + </td> + </tr> + <tr> + <th id="_ar_gkv_i5_label">Why is the change risky/not risky?<br>(and alternatives if risky)</th> + <td><textarea aria-labelledby="_ar_gkv_i5_label"></textarea></td> + </tr> + <tr> + <th id="_ar_gkv_i6_label">String or UUID changes made by this patch</th> + <td><input type="text" class="long" aria-labelledby="_ar_gkv_i6_label"></td> + </tr> + </table> + <p>See <a href="https://wiki.mozilla.org/Release_Management/Uplift_rules" target="_blank">Patch uplifting rules</a> for more info.</p> + </fieldset> +</template> + +<template class="approval-request" data-flags="sec‑approval"> + <fieldset> + <legend>Security Approval Request</legend> + <table> + <tr> + <th id="_ar_sec_i1_label">How easily could an exploit be constructed based on the patch?</th> + <td><textarea aria-labelledby="_ar_sec_i1_label"></textarea></td> + </tr> + <tr> + <th id="_ar_sec_i2_label">Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?</th> + <td> + <div role="radiogroup" class="buttons toggle" aria-labelledby="_ar_sec_i2_label"> + <div class="item"><input id="_ar_sec_i2_r1" type="radio" name="_ar_sec_i2_radio" value="Yes"><label for="_ar_sec_i2_r1">Yes</label></div> + <div class="item"><input id="_ar_sec_i2_r2" type="radio" name="_ar_sec_i2_radio" value="No"><label for="_ar_sec_i2_r2">No</label></div> + <div class="item"><input id="_ar_sec_i2_r3" type="radio" name="_ar_sec_i2_radio" value="Unknown"><label for="_ar_sec_i2_r3">Unknown</label></div> + </div> + </td> + </tr> + <tr> + <th id="_ar_sec_i3_label">Which older supported branches are affected by this flaw?</th> + <td><input type="text" aria-labelledby="_ar_sec_i3_label"></td> + </tr> + <tr> + <th id="_ar_sec_i4_label">If not all supported branches, which [% terms.bug %] introduced the flaw?</th> + <td><input type="text" placeholder="[% terms.Bug %] ID" aria-labelledby="_ar_sec_i4_label" data-type="b[% %]ug"></td> + </tr> + <tr> + <th id="_ar_sec_i5_label">Do you have backports for the affected branches?</th> + <td> + <div role="radiogroup" class="buttons toggle" aria-labelledby="_ar_sec_i5_label"> + <div class="item"><input id="_ar_sec_i5_r1" type="radio" name="_ar_sec_i5_radio" value="Yes"><label for="_ar_sec_i5_r1">Yes</label></div> + <div class="item"><input id="_ar_sec_i5_r2" type="radio" name="_ar_sec_i5_radio" value="No"><label for="_ar_sec_i5_r2">No</label></div> + </div> + </td> + </tr> + <tr> + <th id="_ar_sec_i6_label">If not, how different, hard to create, and risky will they be?</th> + <td><textarea aria-labelledby="_ar_sec_i6_label"></textarea></td> + </tr> + <tr> + <th id="_ar_sec_i7_label">How likely is this patch to cause regressions; how much testing does it need?</th> + <td><textarea aria-labelledby="_ar_sec_i7_label"></textarea></td> + </tr> + </table> + </fieldset> +</template> 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 0566f48b3..6300b0d15 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 @@ -22,6 +22,7 @@ <link rel="shortcut icon" href="extensions/BMO/web/images/favicon.ico"> [% IF bug %] <link rel="canonical" href="[% Bugzilla.localconfig.canonical_urlbase FILTER none %]show_bug.cgi?id=[% bug.bug_id FILTER uri %]"> +<link rel="shorturl" href="[% Bugzilla.localconfig.canonical_urlbase FILTER none %][% bug.bug_id FILTER uri %]"> [% END %] [%# *** Bug List Navigation *** %] diff --git a/extensions/BMO/template/en/default/hook/index-intro.html.tmpl b/extensions/BMO/template/en/default/hook/index-intro.html.tmpl deleted file mode 100644 index ddee1db2f..000000000 --- a/extensions/BMO/template/en/default/hook/index-intro.html.tmpl +++ /dev/null @@ -1,10 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -<a id="docs" class="bz_common_actions" - href="https://bmo.readthedocs.org/"><span>Documentation</span></a> diff --git a/extensions/BMO/template/en/default/pages/persona_deprecated.html.tmpl b/extensions/BMO/template/en/default/pages/persona_deprecated.html.tmpl deleted file mode 100644 index 18b7a3f60..000000000 --- a/extensions/BMO/template/en/default/pages/persona_deprecated.html.tmpl +++ /dev/null @@ -1,53 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% PROCESS global/header.html.tmpl - title = "Persona Deprecated" -%] - -<h2>Persona Deprecated</h2> - -<p> - Beginning on October 25th, 2016, <a href="https://login.persona.org">Persona</a> is no longer a supported authentication method - for bugzilla.mozilla.org (BMO). The Mozilla supported Persona service will cease operations on November 30th, 2016 so therefore - BMO will not longer be able to use the service for authentication. You can go - <a href="https://wiki.mozilla.org/Identity/Persona_Shutdown_Guidelines_for_Reliers">here</a> for more information about Persona - and the reasons for shutting down service. -</p> - -<p> - For users of Persona on BMO, there are two other methods for authentication that are supported and you will need to switch - over to one of them after your current session expires starting October 25th, 2016. -</p> - -<h3>Native Login</h3> - -<p> - BMO has always supported native authentication using a password securely stored in our database. If you have used Persona since - first creating your BMO account, you will probably not know this password. But you can reset it to something you do know by first - logging out, and then clicking on 'Forgot Password' at the right-hand top of the page. Enter your email you used with Persona in - the text field and click 'Reset Password'. -</p> - -<p> - You will receive an email with a link you can use to reset your current password to something you can use from now on. - After you reset your password, simply enter your login and the password in the login fields at the top of any BMO page. -</p> - -<h3>Github Login</h3> - -<p> - <a href="https://github.com">Github</a> is also a BMO supported method of authentication. To use Github, first log out and then - click 'Login' at the top of any BMO page and then click on the 'Github' login image. You will need to have a Github account that - has an email address the same as the Persona email you were using, otherwise a different BMO account will be created. You will - be able to choose the email address you want to use for BMO if you have more than one configured in your Github profile. If none - of the email addresses you have configured in Github match what you were using for Persona, native login described above may be - your best choice if you want to retain your BMO data. -</p> - -[% PROCESS global/footer.html.tmpl %] diff --git a/extensions/BMO/template/en/default/pages/release_tracking_report.html.tmpl b/extensions/BMO/template/en/default/pages/release_tracking_report.html.tmpl index 8ee3d0d59..6c0387ec0 100644 --- a/extensions/BMO/template/en/default/pages/release_tracking_report.html.tmpl +++ b/extensions/BMO/template/en/default/pages/release_tracking_report.html.tmpl @@ -97,7 +97,7 @@ var default_query = '[% default_query FILTER js %]'; </span> </td> </tr> - + <tr> <td> </td> <td colspan="2"> diff --git a/extensions/BMO/template/en/default/pages/upgrade-3.6.html.tmpl b/extensions/BMO/template/en/default/pages/upgrade-3.6.html.tmpl index 9e6d72d66..6091810db 100644 --- a/extensions/BMO/template/en/default/pages/upgrade-3.6.html.tmpl +++ b/extensions/BMO/template/en/default/pages/upgrade-3.6.html.tmpl @@ -74,7 +74,7 @@ <p>Work continues on improving usability for the next release of [%+ terms.Bugzilla %], but the results of the research have already had an impact on this 3.6 release.</p> - + <h4>Improved Quicksearch</h4> <p>The "quicksearch" box that appears on the front page of @@ -113,7 +113,7 @@ <p>There is now a "Browse" link in the header of each [% terms.Bugzilla %] page that presents a very basic interface that allows users to simply browse through all open [% terms.bugs %] in particular components.</p> - + <h4>JSON-RPC Interface</h4> <p>[% terms.Bugzilla %] now has support for the @@ -134,7 +134,7 @@ mandatory.</li> <li><b>[% terms.Bug %] Filing:</b> "Bookmarkable templates" now support the "alias" and "estimated hours" fields.</li> - + <li><b>[% terms.Bug %] Editing:</b> In previous versions of [%+ terms.Bugzilla %], if you added a private comment to [% terms.abug %], then <em>none</em> of the changes that you made at that time were @@ -165,10 +165,10 @@ <li><b>Attachments:</b> When you click on an "attachment 12345" link in a comment, if the attachment is a patch, you will now see the formatted "Diff" view instead of the raw patch.</li> - <li><b>Attachments</b>: For text attachments, we now let the browser + <li><b>Attachments</b>: For text attachments, we now let the browser auto-detect the character encoding, instead of forcing the browser to always assume the attachment is in UTF-8.</li> - + <li><b>Search:</b> You can now display [% terms.bug %] flags as a column in search results.</li> <li><b>Search:</b> When viewing search results, you can see which columns are @@ -188,7 +188,7 @@ <kbd>buglist.cgi</kbd> now accepts nearly every valid field in [%+ terms.Bugzilla %] as a direct URL parameter, like <kbd>&field=value</kbd>.</li> - + <li><b>Requests:</b> When viewing the "My Requests" page, you can now see the lists as a normal search result by clicking a link at the bottom of each table.</li> @@ -208,7 +208,7 @@ if there are no [% terms.bugs %] that match your searches.</li> <li>The arrows in dependency graphs now point the other way, so that [%+ terms.bugs %] point at their dependencies.</li> - + <li><b>New Charts:</b> You can now convert an existing Saved Search into a data series for New Charts.</li> <li><b>New Charts:</b> There is now an interface that allows you to @@ -241,7 +241,7 @@ <li>Information about duplicates is now stored in the database instead of being stored in the <kbd>data/</kbd> directory. On large installations this could save several hundred megabytes of disk space.</li> - + <li>When editing a group, you can now specify that members of a group are allowed to grant others membership in that group itself.</li> <li>The ability to compress BMP attachments to PNGs is now an Extension. 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 5603b943f..1d6e222c6 100644 --- a/extensions/BMO/template/en/default/pages/user_activity.html.tmpl +++ b/extensions/BMO/template/en/default/pages/user_activity.html.tmpl @@ -99,7 +99,7 @@ There used to be an issue in <a href="https://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 + your activity table that could not be regenerated. The changes that could not reliably determine are prefixed by '?'. </p> [% END %] diff --git a/extensions/BMO/web/js/new-bug-frequent-comp.js b/extensions/BMO/web/js/new-bug-frequent-comp.js new file mode 100644 index 000000000..88879738d --- /dev/null +++ b/extensions/BMO/web/js/new-bug-frequent-comp.js @@ -0,0 +1,123 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. */ + +/** + * Reference or define the Bugzilla app namespace. + * @namespace + */ +var Bugzilla = Bugzilla || {}; // eslint-disable-line no-var + +/** + * Show the current user's most-used components on the New Bug page. + */ +Bugzilla.NewBugFrequentComp = class NewBugFrequentComp { + /** + * Initialize a new NewBugFrequentComp instance. + */ + constructor() { + this.$container = document.querySelector('#frequent-components'); + + if (this.$container && BUGZILLA.user.login) { + this.init(); + } + } + + /** + * Initialize the UI. + */ + async init() { + this.$results = this.$container.querySelector('.results'); + this.$message = this.$results.appendChild(document.createElement('p')); + this.$message.textContent = 'Loading...'; + this.$results.setAttribute('aria-busy', 'true'); + this.$container.hidden = false; + + // Get the current params that may contain `cloned_bug_id` and `format` + const current_params = new URLSearchParams(location.search); + + try { + const links = (await this.fetch()).map(({ product, component }) => { + const params = new URLSearchParams(current_params); + + params.append('product', product); + params.append('component', component); + + return { + href: `/enter_bug.cgi?${params.toString()}`, + text: `${product} :: ${component}`, + }; + }); + + this.$message.remove(); + this.$results.insertAdjacentHTML('beforeend', + `<ul>${links.map(({ href, text }) => + `<li><a href="${href.htmlEncode()}">${text.htmlEncode()}</a></li>` + ).join('')}</ul>` + ); + } catch (error) { + this.$message.textContent = error.message || 'Your frequent components could not be retrieved.'; + } + + this.$results.removeAttribute('aria-busy'); + } + + /** + * Retrieve frequently used components. + * @param {Number} [max=10] Maximum number of results. + * @returns {Promise} Results or error. + */ + async fetch(max = 10) { + const params = new URLSearchParams({ + email1: BUGZILLA.user.login, + emailreporter1: '1', + emailtype1: 'exact', + chfield: '[Bug creation]', + chfieldfrom: '-1y', + chfieldto: 'Now', + include_fields: 'product,component', + }); + + return new Promise((resolve, reject) => { + bugzilla_ajax({ + url: `/rest/bug?${params.toString()}` + }, response => { + if (!response.bugs) { + reject(new Error('Your frequent components could not be retrieved.')); + + return; + } + + if (!response.bugs.length) { + reject(new Error(('Your frequent components could not be found.'))); + + return; + } + + const results = []; + + for (const { product, component } of response.bugs) { + const index = results.findIndex(result => product === result.product && component === result.component); + + if (index > -1) { + results[index].count++; + } else { + results.push({ product, component, count: 1 }); + } + } + + // Sort in descending order + results.sort((a, b) => (a.count < b.count ? 1 : a.count > b.count ? -1 : 0)); + + resolve(results.slice(0, max)); + }, () => { + reject(new Error('Your frequent components could not be retrieved.')); + }); + }); + } +}; + +window.addEventListener('DOMContentLoaded', () => new Bugzilla.NewBugFrequentComp(), { once: true }); diff --git a/extensions/BMO/web/js/release_tracking_report.js b/extensions/BMO/web/js/release_tracking_report.js index c91222e0f..158cc7521 100644 --- a/extensions/BMO/web/js/release_tracking_report.js +++ b/extensions/BMO/web/js/release_tracking_report.js @@ -41,7 +41,7 @@ function onProductChange() { '<input type="checkbox" id="field_' + field.id + '_cb" ' + 'onClick="onFieldToggle(this,' + field.id + ')">' + '</td>' + - '<td class="disabled" id="field_' + field.id + '_td">' + + '<td class="disabled" id="field_' + field.id + '_td">' + '<label for="field_' + field.id + '_cb">' + field.desc.htmlEncode() + ':</label>' + '</td>' + diff --git a/extensions/BMO/web/js/sorttable.js b/extensions/BMO/web/js/sorttable.js index 0873dc20a..c20f02647 100644 --- a/extensions/BMO/web/js/sorttable.js +++ b/extensions/BMO/web/js/sorttable.js @@ -3,13 +3,13 @@ version 2 7th April 2007 Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ - + Instructions: Download this file Add <script src="sorttable.js"></script> to your HTML Add class="sortable" to any table you'd like to make sortable Click on the headers to sort - + Thanks to many, many people for contributions and suggestions. Licenced as X11: http://www.kryogenix.org/code/browser/licence.html This basically means: do what you want with it. @@ -25,20 +25,20 @@ sorttable = { arguments.callee.done = true; // kill the timer if (_timer) clearInterval(_timer); - + if (!document.createElement || !document.getElementsByTagName) return; - + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; - + forEach(document.getElementsByTagName('table'), function(table) { if (table.className.search(/\bsortable\b/) != -1) { sorttable.makeSortable(table); } }); - + }, - /* + /* * Prepares the table so that it can be sorted * */ @@ -53,9 +53,9 @@ sorttable = { } // Safari doesn't support table.tHead, sigh if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; - + //if (table.tHead.rows.length != 1) return; // can't cope with two header rows - + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as // "total" rows, for example). This is B&R, since what you're supposed // to do is put them in a tfoot. So, if there are sortbottom rows, @@ -106,7 +106,7 @@ sorttable = { table.sorttable_rows = table_rows; table.sorttable_body_size = body_size; table.sorttable_bodies = bodies; - + // work through each column and calculate its type @@ -185,7 +185,7 @@ sorttable = { _check_already_sorted: function(cell) { if (cell.className.search(/\bsorttable_sorted\b/) != -1) { - // if we're already sorted by this column, just + // if we're already sorted by this column, just // reverse the table, which is quicker sorttable.reverse_table(cell); @@ -194,7 +194,7 @@ sorttable = { } if (cell.className.search(/\bsorttable_sorted_reverse\b/) != -1) { - // if we're already sorted by this column in reverse, just + // if we're already sorted by this column in reverse, just // re-reverse the table, which is quicker sorttable.reverse_table(cell); @@ -271,7 +271,7 @@ sorttable = { return; - // First, remove sorttable_sorted classes from the other header + // First, remove sorttable_sorted classes from the other header // that is currently sorted and its marker (the simbol indicating // that its sorted. sorttable._remove_sorted_classes(this.table.tHead); @@ -285,7 +285,7 @@ sorttable = { sorttable._mark_column_as_sorted(this, '▼', 0); sorttable.sort_table(this); - + }, sort_table: function(cell) { @@ -312,7 +312,7 @@ sorttable = { body_size = cell.table.sorttable_body_size; body_index = 0; - for (var j=0; j<rows.length; j++) { + for (var j=0; j<rows.length; j++) { if (j % 2) rows[j].className = rows[j].className.replace('bz_row_even', 'bz_row_odd'); @@ -336,7 +336,7 @@ sorttable = { cell.table.sorttable_rows = rows; }, - + reverse_table: function(cell) { oldrows = cell.table.sorttable_rows; newrows = []; @@ -348,7 +348,7 @@ sorttable = { tb = cell.table.sorttable_bodies[0]; body_size = cell.table.sorttable_body_size; body_index = 0; - + var BUGLIST = ''; cell.table.sorttable_rows = []; @@ -379,17 +379,17 @@ sorttable = { delete newrows; }, - + guessType: function(table, column) { // guess the type of a column based on its first non-blank row sortfn = sorttable.sort_alpha; for (var i=0; i<table.sorttable_bodies[0].rows.length; i++) { text = sorttable.getInnerText(table.sorttable_bodies[0].rows[i].cells[column]); if (text != '') { - if (text.match(/^-?[Ł$¤]?[\d,.]+%?$/)) { + if (text.match(/^-?[ÂŁ$¤]?[\d,.]+%?$/)) { return sorttable.sort_numeric; } - // check for a date: dd/mm/yyyy or dd/mm/yy + // check for a date: dd/mm/yyyy or dd/mm/yy // can have / or . or - as separator // can be mm/dd as well possdate = text.match(sorttable.DATE_RE) @@ -412,7 +412,7 @@ sorttable = { } return sortfn; }, - + getInnerText: function(node) { // gets the text we want to use for sorting for a cell. // strips leading and trailing whitespace. @@ -422,7 +422,7 @@ sorttable = { hasInputs = (typeof node.getElementsByTagName == 'function') && node.getElementsByTagName('input').length; - + if (typeof node.getAttribute != 'undefined' && node.getAttribute("sorttable_customkey") != null) { return node.getAttribute("sorttable_customkey"); } @@ -457,14 +457,14 @@ sorttable = { } } }, - + /* sort functions each sort function takes two parameters, a and b you are comparing a.sort_data and b.sort_data */ sort_numeric: function(a,b) { aa = parseFloat(a.sort_data.replace(/[^0-9.-]/g,'')); if (isNaN(aa)) aa = 0; - bb = parseFloat(b.sort_data.replace(/[^0-9.-]/g,'')); + bb = parseFloat(b.sort_data.replace(/[^0-9.-]/g,'')); if (isNaN(bb)) bb = 0; return aa-bb; }, @@ -506,7 +506,7 @@ sorttable = { if (dt1<dt2) return -1; return 1; }, - + shaker_sort: function(list, comp_func) { // A stable sort function to allow multi-level sorting of data // see: http://en.wikipedia.org/wiki/Cocktail_sort @@ -536,7 +536,7 @@ sorttable = { b++; } // while(swap) - } + } } /* ****************************************************************** diff --git a/extensions/BMO/web/js/swag.js b/extensions/BMO/web/js/swag.js index cd9561b54..2a86c90f4 100644 --- a/extensions/BMO/web/js/swag.js +++ b/extensions/BMO/web/js/swag.js @@ -24,37 +24,37 @@ function getTotal(item_array) { return total; } -function calculateTotalSwag() { - document.getElementById('Totalswag').value = +function calculateTotalSwag() { + document.getElementById('Totalswag').value = getTotal( new Array('Lanyards', 'Stickers', 'Bracelets', 'Tattoos', 'Buttons', 'Posters')); - + } -function calculateTotalMensShirts() { - document.getElementById('mens_total').value = +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 = +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/choose_product.css b/extensions/BMO/web/styles/choose_product.css index bcca3428e..a4ecf749f 100644 --- a/extensions/BMO/web/styles/choose_product.css +++ b/extensions/BMO/web/styles/choose_product.css @@ -16,6 +16,22 @@ text-align: left; } +#frequent-components ul { + display: flex; + flex-wrap: wrap; + justify-content: center; + margin: 8px auto; + padding: 0; + list-style-type: none; + white-space: nowrap; +} + +#frequent-components li { + flex: none; + margin: 8px 16px; + padding: 0; +} + #product-list { margin: 32px 0; } @@ -23,7 +39,7 @@ #product-list .tile { display: flex; flex-wrap: wrap; - justify-content: flex-start; + justify-content: center; margin: 0 auto; } @@ -55,6 +71,7 @@ } @media screen and (min-width: 1024px) { + #frequent-components ul, #product-list .tile { width: 960px; } @@ -65,6 +82,7 @@ } @media screen and (min-width: 768px) and (max-width: 1023px) { + #frequent-components ul, #product-list .tile { width: 720px; } @@ -75,6 +93,7 @@ } @media screen and (max-width: 767px) { + #frequent-components ul, #product-list .tile { width: auto; max-width: 480px; diff --git a/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl index bcbea3f15..f4cc83c6e 100644 --- a/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl +++ b/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl @@ -391,7 +391,7 @@ <li role="separator"></li> <div class="actions"> <div><a href="buglist.cgi?product=[% bug.product FILTER uri %]&bug_status=__open__" - target="_blank" role="menuitem" tabindex="-1">See All [% terms.Bugs %] in This Product</a></div> + target="_blank" role="menuitem" tabindex="-1">See Open [% terms.Bugs %] in This Product</a></div> <div><a href="enter_bug.cgi?product=[% bug.product FILTER uri %]" target="_blank" role="menuitem" tabindex="-1">File New [% terms.Bug %] in This Product</a></div> <div><button disabled type="button" class="minor component-watching" role="menuitem" tabindex="-1" @@ -449,7 +449,7 @@ <div class="actions"> <div><a href="buglist.cgi?product=[% bug.product FILTER uri %]& [%~ %]component=[% bug.component FILTER uri %]&bug_status=__open__" - target="_blank" role="menuitem" tabindex="-1">See All [% terms.Bugs %] in This Component</a></div> + target="_blank" role="menuitem" tabindex="-1">See Open [% terms.Bugs %] in This Component</a></div> <div><a href="enter_bug.cgi?product=[% bug.product FILTER uri %]& [%~ %]component=[% bug.component FILTER uri %]" target="_blank" role="menuitem" tabindex="-1">File New [% terms.Bug %] in This Component</a></div> diff --git a/extensions/BugModal/web/bug_modal.js b/extensions/BugModal/web/bug_modal.js index a4ae83d72..c15174c8b 100644 --- a/extensions/BugModal/web/bug_modal.js +++ b/extensions/BugModal/web/bug_modal.js @@ -448,7 +448,7 @@ $(function() { $('#action-history') .click(function(event) { event.preventDefault(); - document.location.href = 'show_activity.cgi?id=' + BUGZILLA.bug_id; + window.open(`show_activity.cgi?id=${BUGZILLA.bug_id}`, '_blank'); }); // use scrollTo for in-page activity links @@ -1323,7 +1323,6 @@ $(function() { // finally switch to edit mode if we navigate back to a page that was editing $(window).on('pageshow', restoreEditMode); $(window).on('pageshow', restoreSavedBugComment); - $(window).on('focus', restoreSavedBugComment); restoreEditMode(); restoreSavedBugComment(); }); diff --git a/extensions/BugModal/web/new_bug.js b/extensions/BugModal/web/new_bug.js index 9c1d00854..23fc842cb 100644 --- a/extensions/BugModal/web/new_bug.js +++ b/extensions/BugModal/web/new_bug.js @@ -33,7 +33,7 @@ var component_load = function(product) { function() { alert("Network issues. Please refresh the page and try again"); } - ); + ); } $(document).ready(function() { @@ -101,7 +101,7 @@ $(document).ready(function() { callback(initial.keywords); } }); - + $("#product").on("change", function () { component_load($("#product").val()); }); diff --git a/extensions/BzAPI/Extension.pm b/extensions/BzAPI/Extension.pm index 1f7cce04a..ac9502fcb 100644 --- a/extensions/BzAPI/Extension.pm +++ b/extensions/BzAPI/Extension.pm @@ -22,6 +22,7 @@ use Bugzilla::Util qw(trick_taint datetime_from); use Bugzilla::Constants; use Bugzilla::Install::Filesystem; use Bugzilla::WebService::Constants; +use Module::Runtime qw(require_module); use File::Basename; @@ -279,8 +280,7 @@ sub _preload_handlers { foreach my $module (_resource_modules()) { my $resource_class = "Bugzilla::Extension::BzAPI::Resources::$module"; trick_taint($resource_class); - eval("require $resource_class"); - warn $@ if $@; + eval { require_module($resource_class) }; next if ($@ || !$resource_class->can('rest_handlers')); my $handlers = $resource_class->rest_handlers; next if (ref $handlers ne 'ARRAY' || scalar @$handlers % 2 != 0); diff --git a/extensions/ComponentWatching/template/en/default/hook/global/reason-descs-end.none.tmpl b/extensions/ComponentWatching/template/en/default/hook/global/reason-descs-end.none.tmpl index 8cd67bdff..155bce35c 100644 --- a/extensions/ComponentWatching/template/en/default/hook/global/reason-descs-end.none.tmpl +++ b/extensions/ComponentWatching/template/en/default/hook/global/reason-descs-end.none.tmpl @@ -6,5 +6,5 @@ # defined by the Mozilla Public License, v. 2.0. #%] -[% watch_reason_descs.${constants.REL_COMPONENT_WATCHER} = +[% watch_reason_descs.${constants.REL_COMPONENT_WATCHER} = "You are watching the component for the ${terms.bug}." %] diff --git a/extensions/Example/template/en/default/hook/global/setting-descs-settings.none.tmpl b/extensions/Example/template/en/default/hook/global/setting-descs-settings.none.tmpl index 9dc5fc767..6a4a13a13 100644 --- a/extensions/Example/template/en/default/hook/global/setting-descs-settings.none.tmpl +++ b/extensions/Example/template/en/default/hook/global/setting-descs-settings.none.tmpl @@ -1,6 +1,6 @@ -[% +[% setting_descs.product_chooser = "Product chooser to use when entering $terms.bugs", setting_descs.pretty = "Pretty chooser with common products and icons", setting_descs.full = "Full chooser with all products", setting_descs.small = "Product chooser for mobile devices", -%]
\ No newline at end of file +%] diff --git a/extensions/Example/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/Example/template/en/default/hook/global/user-error-errors.html.tmpl index 50d20a9f2..93f24d159 100644 --- a/extensions/Example/template/en/default/hook/global/user-error-errors.html.tmpl +++ b/extensions/Example/template/en/default/hook/global/user-error-errors.html.tmpl @@ -1,6 +1,6 @@ [%# Note that error messages should generally be indented four spaces, like # below, because when Bugzilla translates an error message into plain - # text, it takes four spaces off the beginning of the lines. + # text, it takes four spaces off the beginning of the lines. # # Note also that I prefixed my error name with "example", the name of my # extension, so that I wouldn't conflict with other error names in diff --git a/extensions/Example/template/en/default/pages/example.html.tmpl b/extensions/Example/template/en/default/pages/example.html.tmpl index 919fa15b4..e265ee55b 100644 --- a/extensions/Example/template/en/default/pages/example.html.tmpl +++ b/extensions/Example/template/en/default/pages/example.html.tmpl @@ -15,12 +15,12 @@ # Portions created by Canonical Ltd. are Copyright (C) 2009 # Canonical Ltd. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] [% PROCESS global/header.html.tmpl - title = "Example Page" + title = "Example Page" %] <p>Here's what you passed me:</p> diff --git a/extensions/FlagDefaultRequestee/template/en/default/hook/admin/flag-type/edit-rows.html.tmpl b/extensions/FlagDefaultRequestee/template/en/default/hook/admin/flag-type/edit-rows.html.tmpl index edefca370..9e8b09c38 100644 --- a/extensions/FlagDefaultRequestee/template/en/default/hook/admin/flag-type/edit-rows.html.tmpl +++ b/extensions/FlagDefaultRequestee/template/en/default/hook/admin/flag-type/edit-rows.html.tmpl @@ -11,7 +11,7 @@ <td> If flag is specifically requestable, this user will be entered in the requestee field by default unless the user changes it.<br> - [% INCLUDE global/userselect.html.tmpl + [% INCLUDE global/userselect.html.tmpl name => 'default_requestee' id => 'default_requestee' value => type.default_requestee.login diff --git a/extensions/FlagTypeComment/template/en/default/flag/type_comment.html.tmpl b/extensions/FlagTypeComment/template/en/default/flag/type_comment.html.tmpl index 88d9d4dd7..56e03040a 100644 --- a/extensions/FlagTypeComment/template/en/default/flag/type_comment.html.tmpl +++ b/extensions/FlagTypeComment/template/en/default/flag/type_comment.html.tmpl @@ -20,35 +20,17 @@ # byron jones <glob@mozilla.com> #%] -[% IF ftc_flags.keys.size %] - <script [% script_nonce FILTER none %]> - YAHOO.util.Event.onDOMReady(function() { - var selects = YAHOO.util.Dom.getElementsByClassName('flag_select'); - for (var i = 0; i < selects.length; i++) { - YAHOO.util.Event.on(selects[i], 'change', ftc_on_change); - } - }); +<link rel="stylesheet" href="extensions/FlagTypeComment/web/styles/ftc.css"> +<script [% script_nonce FILTER none %] src="extensions/FlagTypeComment/web/js/ftc.js"></script> - function ftc_on_change(ev) { - var id = ev.target.id.split('-')[1]; - var state = ev.target.value; - var commentEl = document.getElementById('comment'); - if (!commentEl) return; - [% FOREACH type_id = ftc_flags.keys %] - [% FOREACH state = ftc_states %] - if ([% type_id FILTER none %] == id && '[% state FILTER js %]' == state) { - var text = '[% ftc_flags.$type_id.$state FILTER js %]'; - var value = commentEl.value; - if (value == text) { - return; - } else if (value == '') { - commentEl.value = text; - } else { - commentEl.value = text + "\n\n" + value; - } - } - [% END %] +[% IF ftc_flags.keys.size %] + [%# plaintext templates from database %] + [% FOREACH type_id = ftc_flags.keys %] + [% FOREACH state = ftc_states %] + <meta name="ftc:[% type_id FILTER none %]:[% state FILTER html %]" + content="[% ftc_flags.$type_id.$state FILTER html_linebreak %]"> [% END %] - } - </script> + [% END %] + [%# HTML form templates from extensions %] + [% Hook.process("form") %] [% END %] diff --git a/extensions/FlagTypeComment/web/js/ftc.js b/extensions/FlagTypeComment/web/js/ftc.js new file mode 100644 index 000000000..2682721bc --- /dev/null +++ b/extensions/FlagTypeComment/web/js/ftc.js @@ -0,0 +1,189 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. */ + +/** + * Reference or define the Bugzilla app namespace. + * @namespace + */ +var Bugzilla = Bugzilla || {}; // eslint-disable-line no-var + +/** + * Provide the ability to insert a comment template when a patch's approval flag is selected. + */ +Bugzilla.FlagTypeComment = class FlagTypeComment { + /** + * Initialize a new FlagTypeComment instance. + */ + constructor() { + this.templates = [...document.querySelectorAll('template.approval-request')]; + this.$flags = document.querySelector('#flags'); + this.$comment = document.querySelector('#comment'); + + if (this.$flags && this.$comment) { + this.selects = [...this.$flags.querySelectorAll('.flag_select')]; + this.selects.forEach($select => $select.addEventListener('change', () => this.flag_onselect($select))); + this.$comment.form.addEventListener('submit', () => this.form_onsubmit()); + } + } + + /** + * Check if a `<fieldset>` is compatible with the given flag. For example, `approval‑mozilla‑beta` matches + * `<fieldset data-flags="approval‑mozilla‑beta approval‑mozilla‑release">` while `approval‑mozilla‑esr60` + * matches `<fieldset data-flags="approval‑mozilla‑esr*">`. + * @param {String} name Flag name, such as `approval‑mozilla‑beta`. + * @param {(HTMLFieldSetElement|HTMLTemplateElement)} $element `<fieldset>` or `<template>` element with the + * `data-flags` attribute which is a space-separated list of flag names (wildcard chars can be used). + * @returns {Boolean} Whether the `<fieldset>` is compatible. + */ + check_compatibility(name, $element) { + return !!$element.dataset.flags.split(' ') + .find(_name => !!name.match(new RegExp(`^${_name.replace('*', '.+')}$`, 'i'))); + } + + /** + * Return a list of temporary `<fieldset>`s already inserted to the current page. + * @type {Array<HTMLFieldSetElement>} + */ + get inserted_fieldsets() { + return [...this.$flags.parentElement.querySelectorAll('fieldset.approval-request')]; + } + + /** + * Find a temporary `<fieldset>` already inserted to the current page by a flag name. + * @param {String} name Flag name, such as `approval‑mozilla‑beta`. + * @returns {HTMLFieldSetElement} Any `<fieldset>` element. + */ + find_inserted_fieldset(name) { + return this.inserted_fieldsets.find($fieldset => this.check_compatibility(name, $fieldset)); + } + + /** + * Find an available `<fieldset>` embedded in HTML by a flag name. + * @param {String} name Flag name, such as `approval‑mozilla‑beta`. + * @returns {HTMLFieldSetElement} Any `<fieldset>` element. + */ + find_available_fieldset(name) { + for (const $template of this.templates) { + if (this.check_compatibility(name, $template)) { + const $fieldset = $template.content.cloneNode(true).querySelector('fieldset'); + + $fieldset.className = 'approval-request'; + $fieldset.dataset.flags = $template.dataset.flags; + + return $fieldset; + } + } + + return null; + } + + /** + * Find a `<select>` element for a requested flag that matches the given `<fieldset>`. + * @param {HTMLFieldSetElement} $fieldset `<fieldset>` element with the `data-flags` attribute. + * @returns {HTMLSelectElement} Any `<select>` element. + */ + find_select($fieldset) { + return this.selects + .find($_select => $_select.value === '?' && this.check_compatibility($_select.dataset.name, $fieldset)); + } + + /** + * Add text to the comment box at the end of any existing comment. + * @param {String} text Comment text to be added. + */ + add_comment(text) { + this.$comment.value = this.$comment.value.match(/\S+/g) ? [this.$comment.value, text].join('\n\n') : text; + } + + /** + * Called whenever a flag selection is changed. Insert or remove a comment template. + * @param {HTMLSelectElement} $select `<select>` element that the `change` event is fired. + */ + flag_onselect($select) { + const id = Number($select.dataset.id); + const { name } = $select.dataset; + const state = $select.value; + let $fieldset = this.find_inserted_fieldset(name); + + // Remove the temporary `<fieldset>` if not required. One `<fieldset>` can support multiple flags, so, for example, + // if `approval‑mozilla‑release` is unselected but `approval‑mozilla‑beta` is still selected, keep it + if (state !== '?' && $fieldset && !this.find_select($fieldset)) { + $fieldset.remove(); + } + + // Insert a temporary `<fieldset>` if available + if (state === '?' && !$fieldset) { + $fieldset = this.find_available_fieldset(name); + + if ($fieldset) { + this.$flags.parentElement.appendChild($fieldset); + } + } + + // Insert a traditional plaintext comment template if available + if (!$fieldset) { + const $meta = document.querySelector(`meta[name="ftc:${id}:${state}"]`); + const text = $meta ? $meta.content : ''; + + if (text && this.$comment.value !== text) { + this.add_comment(text); + } + } + } + + /** + * Convert the input values into comment text and remove the temporary `<fieldset>` before submitting the form. + * @returns {Boolean} Always `true` to allow submitting the form. + */ + form_onsubmit() { + for (const $fieldset of this.inserted_fieldsets) { + const text = [ + `[${$fieldset.querySelector('legend').innerText}]`, + ...[...$fieldset.querySelectorAll('tr')].map($tr => { + const checkboxes = [...$tr.querySelectorAll('input[type="checkbox"]:checked')]; + const $radio = $tr.querySelector('input[type="radio"]:checked'); + const $input = $tr.querySelector('textarea,select,input'); + const label = $tr.querySelector('th').innerText.replace(/\n/g, ' '); + let value = ''; + + if (checkboxes.length) { + value = checkboxes.map($checkbox => $checkbox.value.trim()).join(', '); + } else if ($radio) { + value = $radio.value.trim(); + } else if ($input) { + value = $input.value.trim(); + + if ($input.dataset.type === 'bug') { + if (!value) { + value = 'None'; + } else if (!isNaN(value)) { + value = `Bug ${value}`; + } + } + + if ($input.dataset.type === 'bugs') { + if (!value) { + value = 'None'; + } else { + value = value.split(/,\s*/).map(str => (!isNaN(str) ? `Bug ${str}` : str)).join(', '); + } + } + } + + return `${label}: ${value}`; + }), + ].join('\n\n'); + + this.add_comment(text); + $fieldset.remove(); + } + + return true; + } +}; + +window.addEventListener('DOMContentLoaded', () => new Bugzilla.FlagTypeComment()); diff --git a/extensions/FlagTypeComment/web/styles/ftc.css b/extensions/FlagTypeComment/web/styles/ftc.css new file mode 100644 index 000000000..93d190935 --- /dev/null +++ b/extensions/FlagTypeComment/web/styles/ftc.css @@ -0,0 +1,58 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This Source Code Form is "Incompatible With Secondary Licenses", as + * defined by the Mozilla Public License, v. 2.0. */ + +fieldset.approval-request { + margin: 1em 0; +} + +fieldset.approval-request legend { + font-weight: bold; +} + +fieldset.approval-request th { + padding: .4em; + width: 20em; + line-height: 1.25; + font-weight: normal; + text-align: right; + vertical-align: top; + white-space: normal !important; +} + +fieldset.approval-request td { + vertical-align: middle; +} + +fieldset.approval-request label { + font-weight: normal !important; +} + +fieldset.approval-request input[type="text"] { + width: 10em; +} + +fieldset.approval-request input.long[type="text"] { + width: 40em; +} + +fieldset.approval-request textarea { + width: 40em; + min-height: 5em; + font-size: inherit; + line-height: inherit; + font-family: inherit; + resize: vertical; +} + +fieldset.approval-request div { + padding: 0 !important; +} + +fieldset.approval-request table ~ p:last-child { + margin: .4em; + text-align: right; +} diff --git a/extensions/GitHubAuth/Extension.pm b/extensions/GitHubAuth/Extension.pm index 24a7cf2f1..d0d9f42f1 100644 --- a/extensions/GitHubAuth/Extension.pm +++ b/extensions/GitHubAuth/Extension.pm @@ -74,7 +74,7 @@ sub config_modify_panels { my $user_info_class = first { $_->{name} eq 'user_info_class' } @$auth_panel_params; if ($user_info_class) { - push @{ $user_info_class->{choices} }, "GitHubAuth,CGI", "Persona,GitHubAuth,CGI"; + push @{ $user_info_class->{choices} }, "GitHubAuth,CGI"; } my $user_verify_class = first { $_->{name} eq 'user_verify_class' } @$auth_panel_params; diff --git a/extensions/GuidedBugEntry/template/en/default/bug/create/comment-guided.txt.tmpl b/extensions/GuidedBugEntry/template/en/default/bug/create/comment-guided.txt.tmpl index 31408b538..153869f2f 100644 --- a/extensions/GuidedBugEntry/template/en/default/bug/create/comment-guided.txt.tmpl +++ b/extensions/GuidedBugEntry/template/en/default/bug/create/comment-guided.txt.tmpl @@ -1,8 +1,6 @@ [% USE Bugzilla %] [% cgi = Bugzilla.cgi %] User Agent: [% cgi.param('user_agent') %] -[% IF cgi.param('build_id') %] -Build ID: [% cgi.param('build_id') %][% END %] [% IF cgi.param('firefox_for_android') %] Firefox for Android [% END %] diff --git a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl index 7ffa04922..07d814839 100644 --- a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl +++ b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl @@ -351,7 +351,6 @@ Product: <b><span id="dupes_product_name">?</span></b>: <input type="hidden" name="comment" id="comment" value=""> <input type="hidden" name="format" value="guided"> <input type="hidden" name="user_agent" id="user_agent" value=""> -<input type="hidden" name="build_id" id="build_id" value=""> <ul> <li>Please fill out this form clearly, precisely and in as much detail as you can manage.</li> diff --git a/extensions/GuidedBugEntry/web/js/guided.js b/extensions/GuidedBugEntry/web/js/guided.js index 77847fb2e..5f3543153 100644 --- a/extensions/GuidedBugEntry/web/js/guided.js +++ b/extensions/GuidedBugEntry/web/js/guided.js @@ -614,9 +614,6 @@ var bugForm = { onInit: function() { var user_agent = navigator.userAgent; Dom.get('user_agent').value = navigator.userAgent; - if (navigator.buildID && navigator.buildID != navigator.userAgent) { - Dom.get('build_id').value = navigator.buildID; - } Event.addListener(Dom.get('short_desc'), 'blur', function() { Dom.get('dupes_summary').value = Dom.get('short_desc').value; guided.setAdvancedLink(); diff --git a/extensions/GuidedBugEntry/web/js/products.js b/extensions/GuidedBugEntry/web/js/products.js index 8ef1ea0c0..65dc04393 100644 --- a/extensions/GuidedBugEntry/web/js/products.js +++ b/extensions/GuidedBugEntry/web/js/products.js @@ -122,12 +122,12 @@ var products = { "Bugzilla": { support: - 'Please use <a href="https://landfill.bugzilla.org/">Bugzilla Landfill</a> to file "test bugs".' + 'Please use <a href="https://bugzilla-dev.allizom.org/">our test server</a> to file "test bugs".' }, "bugzilla.mozilla.org": { related: [ "Bugzilla" ], support: - 'Please use <a href="https://landfill.bugzilla.org/">Bugzilla Landfill</a> to file "test bugs".' + 'Please use <a href="https://bugzilla-dev.allizom.org/">our test server</a> to file "test bugs".' } }; diff --git a/extensions/InlineHistory/web/inline-history.js b/extensions/InlineHistory/web/inline-history.js index 6b223461e..37f1fec7c 100644 --- a/extensions/InlineHistory/web/inline-history.js +++ b/extensions/InlineHistory/web/inline-history.js @@ -339,7 +339,7 @@ var inline_history = { && flagItem[3] == flagName + flagValue && flagItem[4] == setterIdentity ) { - flagLabel.innerHTML = + flagLabel.innerHTML = '<a href="#' + flagItem[5] + '">' + flagName + '</a>'; break; } diff --git a/extensions/MozReview/Config.pm b/extensions/MozReview/Config.pm deleted file mode 100644 index 34d98907c..000000000 --- a/extensions/MozReview/Config.pm +++ /dev/null @@ -1,16 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Extension::MozReview; - -use 5.10.1; -use strict; -use warnings; - -use constant NAME => 'MozReview'; - -__PACKAGE__->NAME; diff --git a/extensions/MozReview/Extension.pm b/extensions/MozReview/Extension.pm deleted file mode 100644 index 907f12e56..000000000 --- a/extensions/MozReview/Extension.pm +++ /dev/null @@ -1,132 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Extension::MozReview; - -use 5.10.1; -use strict; -use warnings; -use parent qw(Bugzilla::Extension); - -use Bugzilla::Attachment; -use Bugzilla::Error; -use Bugzilla::Extension::MozReview::WebService; -use List::MoreUtils qw( any ); - -our $VERSION = '0.01'; - -my @METHOD_WHITELIST = ( - 'User.get', - 'User.login', - 'User.valid_login', - 'Bug.add_comment', - 'Bug.add_attachment', - 'Bug.attachments', - 'Bug.get', - 'Bug.update_attachment', -); - -BEGIN { - package Bugzilla::User::APIKey; - - sub is_mozreview { - my ($self) = @_; - my $mozreview_app_id = Bugzilla->params->{mozreview_app_id}; - return 0 unless $mozreview_app_id; - - return 1 if $self->app_id && $self->app_id eq $mozreview_app_id; - } -} - -sub template_before_process { - my ($self, $args) = @_; - my $file = $args->{'file'}; - my $vars = $args->{'vars'}; - - return unless (($file =~ /bug\/(show-header|edit).html.tmpl$/ || - $file =~ /bug_modal\/(header|edit).html.tmpl$/ || - $file eq 'attachment/create.html.tmpl') && - Bugzilla->params->{mozreview_base_url}); - - my $bug = exists $vars->{'bugs'} ? $vars->{'bugs'}[0] : $vars->{'bug'}; - - if ($bug) { - if ($file eq 'attachment/create.html.tmpl') { - if ($bug->product eq 'Core' || $bug->product eq 'Firefox' || - $bug->product eq 'Firefox for Android') { - $vars->{'mozreview_enabled'} = 1; - } - } else { - my $has_mozreview = 0; - my $attachments = Bugzilla::Attachment->get_attachments_by_bug($bug); - - foreach my $attachment (@$attachments) { - if ($attachment->contenttype eq 'text/x-review-board-request' - && !$attachment->isobsolete) { - $has_mozreview = 1; - last; - } - } - - if ($has_mozreview) { - $vars->{'mozreview'} = 1; - } - } - } -} - -sub auth_delegation_confirm { - my ($self, $args) = @_; - my $mozreview_callback_url = Bugzilla->params->{mozreview_auth_callback_url}; - my $mozreview_app_id = Bugzilla->params->{mozreview_app_id}; - - return unless $mozreview_callback_url; - return unless $mozreview_app_id; - - if (index($args->{callback}, $mozreview_callback_url) == 0 && $args->{app_id} eq $mozreview_app_id) { - ${$args->{skip_confirmation}} = 1; - } -} - -sub config_add_panels { - my ($self, $args) = @_; - my $modules = $args->{panel_modules}; - $modules->{MozReview} = "Bugzilla::Extension::MozReview::Config"; -} - -sub webservice { - my ($self, $args) = @_; - my $dispatch = $args->{dispatch}; - $dispatch->{MozReview} = "Bugzilla::Extension::MozReview::WebService"; -} - -sub webservice_before_call { - my ($self, $args) = @_; - my ($method, $full_method) = ($args->{method}, $args->{full_method}); - my $mozreview_app_id = Bugzilla->params->{mozreview_app_id} // ''; - my $user = Bugzilla->user; - my $getter = eval { $user->authorizer->successful_info_getter() } or return; - my $app_id = $getter->can("app_id") ? $getter->app_id // '' : ''; - - $full_method =~ s/^Bugzilla::Extension::(\w+)::WebService\./$1./; - - my $is_mozreview_method = $full_method =~ /^MozReview\./; - - if ($is_mozreview_method && (!$mozreview_app_id || !$app_id || $mozreview_app_id ne $app_id)) { - ThrowUserError('forbidden_method', { method => $full_method }); - } - - return unless $mozreview_app_id && $app_id; - - if ($app_id eq $mozreview_app_id && !$is_mozreview_method) { - unless (any { $full_method eq $_ } @METHOD_WHITELIST) { - ThrowUserError('forbidden_method', { method => $full_method }); - } - } -} - -__PACKAGE__->NAME; diff --git a/extensions/MozReview/bin/add-mozreview-children.pl b/extensions/MozReview/bin/add-mozreview-children.pl deleted file mode 100755 index 9faa923fa..000000000 --- a/extensions/MozReview/bin/add-mozreview-children.pl +++ /dev/null @@ -1,257 +0,0 @@ -#!/usr/bin/perl - -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -# This script obsoletes attachments containing URLs to MozReview parent -# review requests and adds attachments, with review flags, for MozReview -# child (commit) review requests to match the new scheme. - -use strict; -use warnings; -use 5.10.1; - -use lib qw(. lib local/lib/perl5); - -BEGIN { - use Bugzilla; - Bugzilla->extensions; -} -use Bugzilla::Constants qw( USAGE_MODE_CMDLINE ); -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -use Bugzilla::Attachment; -use Bugzilla::Bug; -use Bugzilla::Constants; -use Bugzilla::Flag; -use Bugzilla::FlagType; -use JSON; -use LWP::Simple qw( get $ua ); - -$Bugzilla::Flag::disable_flagmail = 1; - -if (my $proxy = Bugzilla->params->{proxy_url}) { - $ua->proxy('https', $proxy); -} - -my $MOZREVIEW_MIMETYPE = 'text/x-review-board-request'; - -# Disable the "cannot ask for review" so we can reassign their flags to -# the new attachments. -Bugzilla->params->{max_reviewer_last_seen} = 0; - -my $rb_host = shift or die "syntax: $0 review-board-url\n"; -$rb_host =~ s#/$##; - -sub rr_url { - my ($rrid) = @_; - return $rb_host . "/r/" . $rrid . "/"; -} - -sub set_review_flag { - my ($child_attach, $flag_type, $flag_status, $reviewer, $setter) = @_; - - my %params = ( - type_id => $flag_type->id, - status => $flag_status - ); - - if ($flag_status eq "?") { - $params{'requestee'} = $reviewer->login; - $params{'setter'} = $setter; - } else { - $params{'setter'} = $reviewer; - } - - return Bugzilla::Flag->set_flag($child_attach, \%params); -} - -my $dbh = Bugzilla->dbh; - -my $bugs_query = "SELECT distinct bug_id FROM attachments WHERE mimetype='text/x-review-board-request' AND isobsolete=0"; -my $bug_ids = $dbh->selectcol_arrayref($bugs_query); -my $total_bugs = scalar @$bug_ids; -$total_bugs or die "No bugs were found.\n"; -my $bug_count = 0; - -print <<EOF; -About to convert MozReview attachments for $total_bugs bugs. - -Press <Ctrl-C> to stop or <Enter> to continue... -EOF -getc(); - -foreach my $bug_id (@$bug_ids) { - $dbh->bz_start_transaction(); - my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); - my $bug_changed = 0; - my $bug = Bugzilla::Bug->new($bug_id); - print "Bug " . $bug->id . " (" . ++$bug_count . "/" . $total_bugs . ")\n"; - - my $url = $rb_host . "/api/extensions/mozreview.extension.MozReviewExtension/summary/?bug=" . $bug->id; - print " Fetching reviews from $url...\n"; - my $body = get($url); - die "Error fetching review requests for bug " . $bug->id - unless defined $body; - - my $data = from_json($body); - my $summaries = $data->{"review_request_summaries"}; - my $attachments = Bugzilla::Attachment->get_attachments_by_bug($bug); - my %attach_map; - - my $flag_types = Bugzilla::FlagType::match({ - 'target_type' => 'attachment', - 'product_id' => $bug->product_id, - 'component_id' => $bug->component_id, - 'is_active' => 1}); - my $flag_type; - - foreach my $ft (@$flag_types) { - if ($ft->is_active && $ft->name eq "review") { - $flag_type = $ft; - last; - } - } - - if (!defined($flag_type)) { - print " Couldn't find flag type for attachments on this bug!\n"; - $dbh->bz_rollback_transaction(); - next; - } - - foreach my $attachment (@$attachments) { - next if ($attachment->isobsolete - || $attachment->contenttype ne $MOZREVIEW_MIMETYPE); - - print " Attachment " . $attachment->id . ": " . $attachment->data . "\n"; - my ($rrid) = $attachment->data =~ m#/r/(\d+)/?$#; - if (!defined($rrid)) { - print " Malformed or missing reviewboard URL\n"; - next; - } - - $attach_map{$attachment->data} = $attachment; - } - - foreach my $summary (@$summaries) { - my $parent = $summary->{"parent"}; - my $attacher = Bugzilla::User->new({ id => $parent->{"submitter_bmo_id"}, - cache => 1 }); - Bugzilla->set_user($attacher); - print " Parent review request " . $parent->{"id"} . "\n"; - - # %parent_flags is used to keep track of review flags related to - # reviewers. It maps requestee => status if status is "?" or - # setter => status otherwise. - my %parent_flags; - - my $parent_url = rr_url($parent->{"id"}); - my $parent_attach = $attach_map{$parent_url}; - if (defined($parent_attach)) { - print " Parent attachment has ID " . $parent_attach->id . ". Obsoleting it.\n"; - foreach my $flag (@{ $parent_attach->flags }) { - if ($flag->type->name eq "review") { - if ($flag->status eq "?") { - $parent_flags{$flag->requestee->id} = $flag; - } else { - $parent_flags{$flag->setter->id} = $flag; - } - } - } - $parent_attach->set_is_obsolete(1); - $parent_attach->update($timestamp); - print " Posting comment.\n"; - $bug->add_comment('', - { isprivate => 0, - type => CMT_ATTACHMENT_UPDATED, - extra_data => $parent_attach->id }); - $bug_changed = 1; - } else { - print " Parent attachment not found.\n"; - } - - my @children = @{ $summary->{"children"} }; - foreach my $child (@children) { - print " Child review request " . $child->{"id"} . "\n"; - my $child_url = rr_url($child->{"id"}); - my $child_attach = $attach_map{$child_url}; - if (defined($child_attach)) { - print " Found attachment.\n"; - next; - } - - print " No attachment found for child " . $child_url . "\n"; - my %child_attach_params = ( - bug => $bug, - data => $rb_host . "/r/" . $child->{"id"} . "/", - description => "MozReview Request: " . $child->{"summary"}, - filename => "reviewboard-" . $child->{"id"} . "-url.txt", - mimetype => $MOZREVIEW_MIMETYPE, - ); - $child_attach = Bugzilla::Attachment->create(\%child_attach_params); - print " New attachment id: " . $child_attach->id . "\n"; - $bug_changed = 1; - - # Set flags. If there was a parent, check it for flags by the - # requestee. Otherwise, set an r? flag. - - # Preserve the original flag hash since we need to modify it for - # every child to find extra reviewers (see below the 'foreach'). - my %tmp_parent_flags = %parent_flags; - - foreach my $reviewer_id (@{ $child->{"reviewers_bmo_ids"} }) { - my $reviewer = Bugzilla::User->new({ id => $reviewer_id, - cache => 1 }); - print " Reviewer " . $reviewer->login . " (" . $reviewer->id . ")\n"; - $reviewer->settings->{block_reviews}->{value} = 'off'; - my $flag = $tmp_parent_flags{$reviewer->id}; - if (defined($flag)) { - print " Flag for reviewer " . $reviewer->id . ": " . $flag->status . "\n"; - - set_review_flag($child_attach, $flag_type, $flag->status, - $reviewer, $attacher); - delete $tmp_parent_flags{$reviewer->id}; - } else { - # No flag on the parent; this probably means the reviewer - # canceled the review, so don't set r?. - print " No review flag for reviewer " . $reviewer->id . "\n"; - } - } - - # Preserve flags that were set directly on the attachment - # from reviewers not listed in the review request. - foreach my $extra_reviewer_id (keys %tmp_parent_flags) { - my $extra_reviewer = Bugzilla::User->new({ - id => $extra_reviewer_id, - cache => 1 - }); - my $flag = $tmp_parent_flags{$extra_reviewer_id}; - print " Extra flag set for reviewer " . $extra_reviewer->login . "\n"; - set_review_flag($child_attach, $flag->type, $flag->status, - $extra_reviewer, $flag->setter); - } - - $child_attach->update($timestamp); - print " Posting comment.\n"; - $bug->add_comment('', - { isprivate => 0, - type => CMT_ATTACHMENT_CREATED, - extra_data => $child_attach->id }); - } - } - - if ($bug_changed) { - print " Updating bug.\n"; - $bug->update($timestamp); - $dbh->do("UPDATE bugs SET lastdiffed = ?, delta_ts = ? WHERE bug_id = ?", - undef, $timestamp, $timestamp, $bug_id); - } - $dbh->bz_commit_transaction(); - Bugzilla->memcached->clear_all(); -} - -print "Done.\n"; diff --git a/extensions/MozReview/disabled b/extensions/MozReview/disabled deleted file mode 100644 index e69de29bb..000000000 --- a/extensions/MozReview/disabled +++ /dev/null diff --git a/extensions/MozReview/lib/Config.pm b/extensions/MozReview/lib/Config.pm deleted file mode 100644 index e0d6377d8..000000000 --- a/extensions/MozReview/lib/Config.pm +++ /dev/null @@ -1,55 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Extension::MozReview::Config; - -use 5.10.1; -use strict; -use warnings; - -use Bugzilla::Config::Common; - -our $sortkey = 1300; - -sub get_param_list { - my ($class) = @_; - - my @params = ( - { - name => 'mozreview_base_url', - type => 't', - default => '', - checker => \&check_urlbase - }, - { - name => 'mozreview_auth_callback_url', - type => 't', - default => '', - checker => sub { - my ($url) = (@_); - - return 'must be an HTTP/HTTPS absolute URL' unless $url =~ m{^https?://}; - return ''; - } - }, - { - name => 'mozreview_app_id', - type => 't', - default => '', - checker => sub { - my ($app_id) = (@_); - - return 'must be a hex number' unless $app_id =~ /^[[:xdigit:]]+$/; - return ''; - }, - }, - ); - - return @params; -} - -1; diff --git a/extensions/MozReview/lib/WebService.pm b/extensions/MozReview/lib/WebService.pm deleted file mode 100644 index c6916d1fa..000000000 --- a/extensions/MozReview/lib/WebService.pm +++ /dev/null @@ -1,209 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Extension::MozReview::WebService; - -use 5.10.1; -use strict; -use warnings; - -use base qw(Bugzilla::WebService); - -use Bugzilla::Attachment; -use Bugzilla::Bug; -use Bugzilla::Comment; -use Bugzilla::Constants; -use Bugzilla::Error; -use Bugzilla::WebService::Constants; -use Bugzilla::WebService::Util qw(extract_flags validate translate); -use Bugzilla::Util qw(trim); - -use List::MoreUtils qw(uniq all); -use List::Util qw(max); -use Storable qw(dclone); - -use constant PUBLIC_METHODS => qw( attachments ); - -BEGIN { - *_attachment_to_hash = \&Bugzilla::WebService::Bug::_attachment_to_hash; - *_flag_to_hash = \&Bugzilla::WebService::Bug::_flag_to_hash; -} - -sub attachments { - my ($self, $params) = validate(@_, 'attachments'); - my $dbh = Bugzilla->dbh; - - # BMO: Don't allow updating of bugs if disabled - if (Bugzilla->params->{disable_bug_updates}) { - ThrowErrorPage('bug/process/updates-disabled.html.tmpl', - 'Bug updates are currently disabled.'); - } - - my $user = Bugzilla->login(LOGIN_REQUIRED); - - ThrowCodeError('param_required', { param => 'attachments' }) - unless defined $params->{attachments}; - - my $bug = Bugzilla::Bug->check($params->{bug_id}); - - ThrowUserError("product_edit_denied", { product => $bug->product }) - unless $user->can_edit_product($bug->product_id); - - my (@modified, @created); - $dbh->bz_start_transaction(); - my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); - - my $comment_tags = $params->{comment_tags}; - my $attachments = $params->{attachments}; - - if ($comment_tags) { - ThrowUserError('comment_tag_disabled') - unless Bugzilla->params->{comment_taggers_group}; - - my $all_mozreview_tags = all { /^mozreview-?/i } @$comment_tags; - if ($all_mozreview_tags || $user->can_tag_comments) { - # there should be a method of User that does this. - local $user->{can_tag_comments} = 1; - $bug->set_all({ comment_tags => $comment_tags }); - } - else { - ThrowUserError('auth_failure', - { group => Bugzilla->params->{comment_taggers_group}, - action => 'update', - object => 'comment_tags' }) - } - } - - foreach my $attachment (@$attachments) { - my $flags = delete $attachment->{flags}; - my $attachment_id = delete $attachment->{attachment_id}; - my $comment = delete $attachment->{comment}; - my $attachment_obj; - - if ($attachment_id) { - $attachment_obj = Bugzilla::Attachment->check({ id => $attachment_id }); - ThrowUserError("mozreview_attachment_bug_mismatch", { bug => $bug, attachment => $attachment_obj }) - if $attachment_obj->bug_id != $bug->id; - - # HACK: preload same bug object. - $attachment_obj->{bug} = $bug; - - $attachment = translate($attachment, Bugzilla::WebService::Bug::ATTACHMENT_MAPPED_SETTERS); - - my ($update_flags, $new_flags) = $flags - ? extract_flags($flags, $bug, $attachment_obj) - : ([], []); - if ($attachment_obj->validate_can_edit) { - $attachment_obj->set_all($attachment); - $attachment_obj->set_flags($update_flags, $new_flags) if $flags; - } - elsif (scalar @$update_flags && !scalar(@$new_flags) && !scalar keys %$attachment) { - # Requestees can set flags targetted to them, even if they cannot - # edit the attachment. Flag setters can edit their own flags too. - my %flag_list = map { $_->{id} => $_ } @$update_flags; - my $flag_objs = Bugzilla::Flag->new_from_list([ keys %flag_list ]); - my @editable_flags; - foreach my $flag_obj (@$flag_objs) { - if ($flag_obj->setter_id == $user->id - || ($flag_obj->requestee_id && $flag_obj->requestee_id == $user->id)) - { - push(@editable_flags, $flag_list{$flag_obj->id}); - } - } - if (!scalar @editable_flags) { - ThrowUserError('illegal_attachment_edit', { attach_id => $attachment_obj->id }); - } - $attachment_obj->set_flags(\@editable_flags, []); - } - else { - ThrowUserError('illegal_attachment_edit', { attach_id => $attachment_obj->id }); - } - - my $changes = $attachment_obj->update($timestamp); - - if (my $comment_text = trim($comment)) { - $attachment_obj->bug->add_comment($comment_text, - { isprivate => $attachment_obj->isprivate, - type => CMT_ATTACHMENT_UPDATED, - extra_data => $attachment_obj->id }); - } - - $changes = translate($changes, Bugzilla::WebService::Bug::ATTACHMENT_MAPPED_RETURNS); - - my %hash = ( - id => $self->type('int', $attachment_obj->id), - last_change_time => $self->type('dateTime', $attachment_obj->modification_time), - changes => {}, - ); - - foreach my $field (keys %$changes) { - my $change = $changes->{$field}; - - # We normalize undef to an empty string, so that the API - # stays consistent for things like Deadline that can become - # empty. - $hash{changes}->{$field} = { - removed => $self->type('string', $change->[0] // ''), - added => $self->type('string', $change->[1] // '') - }; - } - - push(@modified, \%hash); - } - else { - $attachment_obj = Bugzilla::Attachment->create({ - bug => $bug, - creation_ts => $timestamp, - data => $attachment->{data}, - description => $attachment->{summary}, - filename => $attachment->{file_name}, - mimetype => $attachment->{content_type}, - ispatch => $attachment->{is_patch}, - isprivate => $attachment->{is_private}, - }); - - if ($flags) { - my ($old_flags, $new_flags) = extract_flags($flags, $bug, $attachment_obj); - $attachment_obj->set_flags($old_flags, $new_flags); - } - - push(@created, $attachment_obj); - - $attachment_obj->update($timestamp); - $bug->add_comment($comment, - { isprivate => $attachment_obj->isprivate, - type => CMT_ATTACHMENT_CREATED, - extra_data => $attachment_obj->id }); - - } - } - - $bug->update($timestamp); - - $dbh->bz_commit_transaction(); - $bug->send_changes(); - - my %attachments_created = map { $_->id => $self->_attachment_to_hash($_, $params) } @created; - my %attachments_modified = map { (ref $_->{id} ? $_->{id}->value : $_->{id}) => $_ } @modified; - - return { attachments_created => \%attachments_created, attachments_modified => \%attachments_modified }; -} - -sub rest_resources { - return [ - qr{^/mozreview/(\d+)/attachments$}, { - POST => { - method => 'attachments', - params => sub { - return { bug_id => $1 }; - }, - }, - }, - ]; -} - -1; diff --git a/extensions/MozReview/template/en/default/admin/params/mozreview.html.tmpl b/extensions/MozReview/template/en/default/admin/params/mozreview.html.tmpl deleted file mode 100644 index 4a35555a4..000000000 --- a/extensions/MozReview/template/en/default/admin/params/mozreview.html.tmpl +++ /dev/null @@ -1,20 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% - title = "MozReview" - desc = "Configure MozReview" -%] - -[% - param_descs = { - mozreview_base_url => 'MozReview Base URL', - mozreview_auth_callback_url => 'MozReview Auth Delegation URL', - mozreview_app_id => 'app_id for API Keys delegated to MozReview', - } -%] diff --git a/extensions/MozReview/template/en/default/hook/attachment/create-before_form.html.tmpl b/extensions/MozReview/template/en/default/hook/attachment/create-before_form.html.tmpl deleted file mode 100644 index bfa842c89..000000000 --- a/extensions/MozReview/template/en/default/hook/attachment/create-before_form.html.tmpl +++ /dev/null @@ -1,17 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% RETURN UNLESS mozreview_enabled %] - -<div class="mozreview-ad"> - Are you attaching a patch? Consider trying out - <a href="https://reviewboard.mozilla.org/">MozReview</a>, Mozilla's - new repository-based code-review tool. - <a href="https://mozilla-version-control-tools.readthedocs.io/en/latest/mozreview.html">Read - the docs</a> to get started. -</div> diff --git a/extensions/MozReview/template/en/default/hook/attachment/edit-view.html.tmpl b/extensions/MozReview/template/en/default/hook/attachment/edit-view.html.tmpl deleted file mode 100644 index 044c36ae9..000000000 --- a/extensions/MozReview/template/en/default/hook/attachment/edit-view.html.tmpl +++ /dev/null @@ -1,16 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% - RETURN UNLESS attachment.mimetype == "text/x-review-board-request" && attachment.external_redirect; - custom_attachment_viewer = 1; - url = attachment.data; -%] -<h3> - <a href="[% url FILTER html %]" title="[% url FILTER html %]">Show review on MozReview</a><br> -</h3> diff --git a/extensions/MozReview/template/en/default/hook/bug/edit-after_bug_data.html.tmpl b/extensions/MozReview/template/en/default/hook/bug/edit-after_bug_data.html.tmpl deleted file mode 100644 index b0e4ce600..000000000 --- a/extensions/MozReview/template/en/default/hook/bug/edit-after_bug_data.html.tmpl +++ /dev/null @@ -1,35 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% RETURN UNLESS mozreview %] - -<table class="mozreview-table"> - <thead> - <tr> - <th>MozReview Requests</th> - </tr> - </thead> - - <tbody> - <tr> - <td> - [% INCLUDE moz_review/table.html.tmpl %] - </td> - </tr> - </tbody> - - <tfoot> - <tr class="mozreview-hide-discarded-row bz_default_hidden"> - <td class="mozreview-hide-discarded"> - <a class="mozreview-hide-discarded-link" - href="#"><span class="mozreview-discarded-action">Show</span> - discarded requests</a> - </td> - </tr> - </tfoot> -</table> diff --git a/extensions/MozReview/template/en/default/hook/bug/show-header-end.html.tmpl b/extensions/MozReview/template/en/default/hook/bug/show-header-end.html.tmpl deleted file mode 100644 index d70e36b57..000000000 --- a/extensions/MozReview/template/en/default/hook/bug/show-header-end.html.tmpl +++ /dev/null @@ -1,13 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% - IF mozreview; - PROCESS moz_review/header.html.tmpl; - END; -%] diff --git a/extensions/MozReview/template/en/default/hook/bug_modal/edit-module.html.tmpl b/extensions/MozReview/template/en/default/hook/bug_modal/edit-module.html.tmpl deleted file mode 100644 index 9785fa0bd..000000000 --- a/extensions/MozReview/template/en/default/hook/bug_modal/edit-module.html.tmpl +++ /dev/null @@ -1,21 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% RETURN UNLESS mozreview %] - -[% WRAPPER bug_modal/module.html.tmpl - title = "MozReview Requests" - collapsed = 0 -%] - [% INCLUDE moz_review/table.html.tmpl %] - <div class="mozreview-hide-discarded-row bz_default_hidden"> - <button type="button" class="minor mozreview-hide-discarded-link"> - <span class="mozreview-discarded-action">Show</span> discarded requests - </button> - </div> -[% END %] diff --git a/extensions/MozReview/template/en/default/hook/bug_modal/header-end.html.tmpl b/extensions/MozReview/template/en/default/hook/bug_modal/header-end.html.tmpl deleted file mode 100644 index d70e36b57..000000000 --- a/extensions/MozReview/template/en/default/hook/bug_modal/header-end.html.tmpl +++ /dev/null @@ -1,13 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% - IF mozreview; - PROCESS moz_review/header.html.tmpl; - END; -%] diff --git a/extensions/MozReview/template/en/default/hook/global/header-start.html.tmpl b/extensions/MozReview/template/en/default/hook/global/header-start.html.tmpl deleted file mode 100644 index 6ad026de6..000000000 --- a/extensions/MozReview/template/en/default/hook/global/header-start.html.tmpl +++ /dev/null @@ -1,11 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% IF template.name == 'attachment/create.html.tmpl' %] - [% style_urls.push('extensions/MozReview/web/style/attachment.css') %] -[% END %] diff --git a/extensions/MozReview/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/MozReview/template/en/default/hook/global/user-error-errors.html.tmpl deleted file mode 100644 index 151e63b21..000000000 --- a/extensions/MozReview/template/en/default/hook/global/user-error-errors.html.tmpl +++ /dev/null @@ -1,15 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% IF error == "forbidden_method" %] - The requested method '[% method FILTER html %]' is not allowed to be called using the current API Key. -[% ELSIF error == "mozreview_attachment_bug_mismatch" %] - You tried to update attachment [% attachment.id FILTER html %] - as part of adding or updating attachments on [% bug.id FILTER html %]. - That attachment actually belongs to [% terms.bug %] [% attachment.bug_id FILTER html %]. -[% END %] diff --git a/extensions/MozReview/template/en/default/moz_review/header.html.tmpl b/extensions/MozReview/template/en/default/moz_review/header.html.tmpl deleted file mode 100644 index 99fb81ba4..000000000 --- a/extensions/MozReview/template/en/default/moz_review/header.html.tmpl +++ /dev/null @@ -1,10 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% style_urls.push('extensions/MozReview/web/style/mozreview.css') %] -[% javascript_urls.push('extensions/MozReview/web/js/mozreview.js') %] diff --git a/extensions/MozReview/template/en/default/moz_review/table.html.tmpl b/extensions/MozReview/template/en/default/moz_review/table.html.tmpl deleted file mode 100644 index 84b7add47..000000000 --- a/extensions/MozReview/template/en/default/moz_review/table.html.tmpl +++ /dev/null @@ -1,28 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -<table class="mozreview-requests" data-mozreview-url="[% Bugzilla.params.mozreview_base_url FILTER html %]"> - <thead> - <tr> - <th>Submitter</th> - <th>Diff</th> - <th>Changes</th> - <th>Open Issues</th> - <th>Last Updated</th> - </tr> - </thead> - <tbody class="mozreview-request"> - <tr class="mozreview-loading-row"> - <td colspan="4">Loading...</td> - </tr> - <tr class="mozreview-loading-error-row bz_default_hidden"> - <td colspan="4">Error loading review requests: - <span class="mozreview-load-error-string"></span></td> - </tr> - </tbody> -</table> diff --git a/extensions/MozReview/web/js/mozreview.js b/extensions/MozReview/web/js/mozreview.js deleted file mode 100644 index 6fe51f53b..000000000 --- a/extensions/MozReview/web/js/mozreview.js +++ /dev/null @@ -1,134 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This Source Code Form is "Incompatible With Secondary Licenses", as - * defined by the Mozilla Public License, v. 2.0. - */ - -var MozReview = {}; - -MozReview.getReviewRequest = function() { - var hostUrl = $('.mozreview-requests').data('mozreviewUrl'); - var tr = $('<tr/>'); - var td = $('<td/>'); - var link = $('<a/>'); - - var rrSummaryApiUrl = hostUrl + - 'api/extensions/mozreview.extension.MozReviewExtension/summary/?bug=' + - BUGZILLA.bug_id; - var rrUiBaseUrl = hostUrl + 'r/'; - - function rrUrl(rrId) { - return rrUiBaseUrl + rrId + '/'; - } - - function rrDiffUrl(rrId) { - return rrUrl(rrId) + 'diff/#index_header'; - } - - function humanizedInt(i) { - if (i > 1000) { - return (i / 1000).toFixed(1) + 'k'; - } else { - return '' + i; - } - } - - function rrCommitRow(rr, firstCommit) { - var trCommit = tr.clone(); - var tdSubmitter = td.clone(); - var tdSummary = td.clone(); - var diffLink = link.clone(); - var diffStat = ''; - - if (firstCommit) { - tdSubmitter.text(rr.submitter); - } - - tdSummary.addClass('mozreview-summary'); - diffLink.attr('href', rrDiffUrl(rr.id)); - diffLink.text(rr.summary); - tdSummary.append(diffLink); - - if (rr.diff.insert > 0) { - diffStat = '+' + humanizedInt(rr.diff.insert); - } - - if (rr.diff.delete > 0) { - if (diffStat.length > 0) { - diffStat += ' / '; - } - diffStat += '-' + humanizedInt(rr.diff.delete); - } - - trCommit.append( - tdSubmitter, - tdSummary, - td.clone().text(diffStat) - .addClass('mozreview-diffstat'), - td.clone().text(rr.issue_open_count) - .addClass('mozreview-open-issues'), - td.clone().text(timeAgo(new Date(rr.last_updated))) - ); - - if (rr.status == "discarded") { - $('.mozreview-hide-discarded-row').removeClass('bz_default_hidden'); - trCommit.addClass('bz_default_hidden mozreview-discarded-request'); - } - - return trCommit; - } - - $('.mozreview-hide-discarded-link').click(function(event) { - event.preventDefault(); - if ($('.bz_default_hidden.mozreview-discarded-request').length) { - $('.mozreview-discarded-request').removeClass('bz_default_hidden'); - $('.mozreview-discarded-action').text('Hide'); - } else { - $('.mozreview-discarded-request').addClass('bz_default_hidden'); - $('.mozreview-discarded-action').text('Show'); - } - }); - - var tbody = $('tbody.mozreview-request'); - - function displayLoadError(errStr) { - var errRow = tbody.find('.mozreview-loading-error-row'); - errRow.find('.mozreview-load-error-string').text(errStr); - errRow.removeClass('bz_default_hidden'); - } - - $.getJSON(rrSummaryApiUrl, function(data) { - var family, parent, i, j; - - if (data.review_request_summaries.length === 0) { - displayLoadError('none returned from server'); - } else { - for (i = 0; i < data.review_request_summaries.length; i++) { - family = data.review_request_summaries[i]; - for (j = 0; j < family.children.length; j++) { - tbody.append(rrCommitRow(family.children[j], j == 0)); - } - } - } - - tbody.find('.mozreview-loading-row').addClass('bz_default_hidden'); - }).fail(function(jqXHR, textStatus, errorThrown) { - var errStr; - if (jqXHR.responseJSON && jqXHR.responseJSON.err && - jqXHR.responseJSON.err.msg) { - errStr = jqXHR.responseJSON.err.msg; - } else if (errorThrown) { - errStr = errorThrown; - } else { - errStr = 'unknown'; - } - displayLoadError(errStr); - tbody.find('.mozreview-loading-row').addClass('bz_default_hidden'); - }); -}; - -$().ready(function() { - MozReview.getReviewRequest(); -}); diff --git a/extensions/MozReview/web/style/attachment.css b/extensions/MozReview/web/style/attachment.css deleted file mode 100644 index 474bf466e..000000000 --- a/extensions/MozReview/web/style/attachment.css +++ /dev/null @@ -1,13 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This Source Code Form is "Incompatible With Secondary Licenses", as - * defined by the Mozilla Public License, v. 2.0. */ - -.mozreview-ad { - background-color: #fff9db; - color: #666458; - padding: 5px; - margin-bottom: 10px; -} diff --git a/extensions/MozReview/web/style/mozreview.css b/extensions/MozReview/web/style/mozreview.css deleted file mode 100644 index a2263fc11..000000000 --- a/extensions/MozReview/web/style/mozreview.css +++ /dev/null @@ -1,79 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This Source Code Form is "Incompatible With Secondary Licenses", as - * defined by the Mozilla Public License, v. 2.0. */ - -.mozreview-table { - background: #fff; - border: none; - border-collapse: collapse; - border-bottom: 1px solid rgba(0, 0, 0, 0.2); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); -} - -.mozreview-table th { - text-align: left; - padding: 4px; -} - -.mozreview-table td { - vertical-align: middle !important; - padding: 4px !important; -} - -.mozreview-table thead, .mozreview-table tfoot { - background-color: #eee; - color: #404040; -} - -.mozreview-requests { - background: #fff; - border: none; - border-collapse: collapse; -} - -.mozreview-requests th { - padding: 2px; -} - -.mozreview-requests td { - padding: 2px; -} - -.mozreview-requests .mozreview-summary { - text-align: left; -} - -.mozreview-requests .mozreview-open-issues { - text-align: center; -} - -.mozreview-requests .mozreview-diffstat { - text-align: center; - white-space: nowrap; -} - -/* bug-modal specific */ - -#module-mozreview-requests .module-content { - padding: 0; -} - -.bug_modal .mozreview-table { - width: 100%; -} - -.bug_modal .mozreview-request td { - padding-left: 8px; -} - -.bug_modal .mozreview-requests th { - text-align: left; - padding-left: 8px; -} - -.bug_modal .mozreview-hide-discarded-row { - padding: 4px; -} diff --git a/extensions/MyDashboard/template/en/default/hook/account/prefs/saved-searches-saved-row.html.tmpl b/extensions/MyDashboard/template/en/default/hook/account/prefs/saved-searches-saved-row.html.tmpl index cd6a36705..ccc54c42a 100644 --- a/extensions/MyDashboard/template/en/default/hook/account/prefs/saved-searches-saved-row.html.tmpl +++ b/extensions/MyDashboard/template/en/default/hook/account/prefs/saved-searches-saved-row.html.tmpl @@ -7,7 +7,7 @@ #%] <td align="center"> - <input type="checkbox" + <input type="checkbox" name="in_mydashboard_[% q.id FILTER html %]" value="1" alt="[% q.name FILTER html %]" diff --git a/extensions/MyDashboard/template/en/default/pages/mydashboard.html.tmpl b/extensions/MyDashboard/template/en/default/pages/mydashboard.html.tmpl index 5c372db3c..734be28df 100644 --- a/extensions/MyDashboard/template/en/default/pages/mydashboard.html.tmpl +++ b/extensions/MyDashboard/template/en/default/pages/mydashboard.html.tmpl @@ -45,7 +45,7 @@ <td class="field_data"> {{#if removed}} {{#unless added}} - Removed: + Removed: {{/unless}} {{removed}} {{/if}} @@ -127,30 +127,29 @@ %] </div> + [% IF Param('phabricator_enabled') %] + <div class="query_heading requests"> + <a href="[% Param('phabricator_base_uri') %]/differential">Phabricator Review Requests</a> + </div> + [% END %] + [% BLOCK requests_table %] <div id="[% name FILTER html %]_container" class="requests"> - <div class="query_heading">[% title FILTER html_light %]</div> - <span id="[% name FILTER html %]_loading" class="items_found">Loading...</span> - <span id="[% name FILTER html %]_count_refresh" class="bz_default_hidden"> - <span class="items_found" id="[% name FILTER html %]_flags_found">0 reviews found</span> - | <a class="refresh" href="javascript:void(0);" id="[% name FILTER html %]_refresh">Refresh</a> - | <a class="buglist" href="javascript:void(0);" id="[% name FILTER html %]_buglist">Buglist</a> - </span> - <div id="[% name FILTER html %]_table"></div> + <div class="query_heading">[% title FILTER html_light %]</div> + <span id="[% name FILTER html %]_loading" class="items_found">Loading...</span> + <span id="[% name FILTER html %]_count_refresh" class="bz_default_hidden"> + <span class="items_found" id="[% name FILTER html %]_flags_found">0 reviews found</span> + | <a class="refresh" href="javascript:void(0);" id="[% name FILTER html %]_refresh">Refresh</a> + | <a class="buglist" href="javascript:void(0);" id="[% name FILTER html %]_buglist">Buglist</a> + </span> + <div id="[% name FILTER html %]_table"></div> </div> [% END %] - [% ## no-008filter - # requires PhabBugz extension - IF Param('phabricator_enabled'); - title = '<a href="' _ Param('phabricator_base_uri') _ '">Phabricator</a> Reviews Requested of You'; - PROCESS requests_table name='reviews' title=title; - END; - - PROCESS requests_table name='requestee' title='Flags Requested of You'; - PROCESS requests_table name='requester' title='Flags You Have Requested'; - %] + [% PROCESS requests_table name='requestee' title='Flags Requested of You' %] + [% PROCESS requests_table name='requester' title='Flags You Have Requested' %] </div> + <div style="clear:both;"></div> [% IF user.showmybugslink OR user.queries.size OR user.queries_subscribed.size %] <hr> diff --git a/extensions/MyDashboard/web/js/flags.js b/extensions/MyDashboard/web/js/flags.js index 8931e277a..b340b4ee1 100644 --- a/extensions/MyDashboard/web/js/flags.js +++ b/extensions/MyDashboard/web/js/flags.js @@ -16,18 +16,15 @@ $(function () { // Common var counter = 0; var dataSource = { - reviews: null, requestee: null, requester: null }; var dataTable = { - reviews: null, requestee: null, requester: null }; - var hasReviews = !!document.getElementById('reviews_container'); - var updateRequestsTable = function(type) { + var updateFlagTable = function(type) { if (!type) return; counter = counter + 1; @@ -50,15 +47,14 @@ $(function () { if (o.error && o.error.message) { alert("Failed to load requests:\n\n" + o.error.message); } else { - alert("Failed to load requests."); + alert("Failed to load requests"); } } }; - var method = type === 'reviews' ? 'PhabBugz.needs_review' : 'MyDashboard.run_flag_query'; var json_object = { version: "1.1", - method: method, + method: "MyDashboard.run_flag_query", id: counter, params: { type : type, @@ -138,84 +134,6 @@ $(function () { } }; - var phabAuthorFormatter = function(o) { - return '<span title="' + Y.Escape.html(o.data.author_email) + '">' + - Y.Escape.html(o.data.author_name) + '</span>'; - }; - - var phabRowFormatter = function(o) { - var row = o.cell.ancestor(); - - // space in the 'flags' tables is tight - // render requests as two rows - diff title on first row, columns - // on second - - row.insert( - '<tr class="' + row.getAttribute('class') + '">' + - '<td class="yui3-datatable-cell" colspan="4">' + - '<a href="' + o.data.url + '" target="_blank">' + - Y.Escape.html(o.data.title) + '</a></td></tr>', - 'after'); - - o.cell.setHTML('<a href="' + o.data.url + '">D' + o.data.id + '</a>'); - - return false; - }; - - // Reviews - if (hasReviews) { - dataSource.reviews = new Y.DataSource.IO({ source: 'jsonrpc.cgi' }); - dataSource.reviews.on('error', function(e) { - console.log(e); - try { - var response = Y.JSON.parse(e.data.responseText); - if (response.error) - e.error.message = response.error.message; - } catch(ex) { - // ignore - } - }); - dataTable.reviews = new Y.DataTable({ - columns: [ - { key: 'author_email', label: 'Requester', sortable: true, - formatter: phabAuthorFormatter, allowHTML: true }, - { key: 'id', label: 'Revision', sortable: true, - nodeFormatter: phabRowFormatter, allowHTML: true }, - { key: 'bug_id', label: 'Bug', sortable: true, - formatter: bugLinkFormatter, allowHTML: true }, - { key: 'updated', label: 'Updated', sortable: true, - formatter: updatedFormatter, allowHTML: true } - ], - strings: { - emptyMessage: 'No review requests.', - } - }); - - dataTable.reviews.plug(Y.Plugin.DataTableSort); - - dataTable.reviews.plug(Y.Plugin.DataTableDataSource, { - datasource: dataSource.reviews - }); - - dataSource.reviews.plug(Y.Plugin.DataSourceJSONSchema, { - schema: { - resultListLocator: 'result.result', - resultFields: [ 'author_email', 'author_name', 'bug_id', - 'bug_status', 'bug_summary', 'id', 'status', 'title', - 'updated', 'updated_fancy', 'url' ] - } - }); - - dataTable.reviews.render("#reviews_table"); - - Y.one('#reviews_refresh').on('click', function(e) { - updateRequestsTable('reviews'); - }); - Y.one('#reviews_buglist').on('click', function(e) { - loadBugList('reviews'); - }); - } - // Requestee dataSource.requestee = new Y.DataSource.IO({ source: 'jsonrpc.cgi' }); dataSource.requestee.on('error', function(e) { @@ -259,7 +177,7 @@ $(function () { dataTable.requestee.render("#requestee_table"); Y.one('#requestee_refresh').on('click', function(e) { - updateRequestsTable('requestee'); + updateFlagTable('requestee'); }); Y.one('#requestee_buglist').on('click', function(e) { loadBugList('requestee'); @@ -307,23 +225,18 @@ $(function () { }); Y.one('#requester_refresh').on('click', function(e) { - updateRequestsTable('requester'); + updateFlagTable('requester'); }); Y.one('#requester_buglist').on('click', function(e) { loadBugList('requester'); }); // Initial load - if (hasReviews) { - Y.on("contentready", function (e) { - updateRequestsTable('reviews'); - }, "#reviews_table"); - } Y.on("contentready", function (e) { - updateRequestsTable("requestee"); + updateFlagTable("requestee"); }, "#requestee_table"); Y.on("contentready", function (e) { - updateRequestsTable("requester"); + updateFlagTable("requester"); }, "#requester_table"); }); }); diff --git a/extensions/MyDashboard/web/js/query.js b/extensions/MyDashboard/web/js/query.js index e5e0979a1..53139d27f 100644 --- a/extensions/MyDashboard/web/js/query.js +++ b/extensions/MyDashboard/web/js/query.js @@ -14,7 +14,7 @@ if (typeof(MyDashboard) == 'undefined') { $(function() { YUI({ base: 'js/yui3/', - combine: false, + combine: false, groups: { gallery: { combine: false, diff --git a/extensions/OldBugMove/template/en/default/admin/params/oldbugmove.html.tmpl b/extensions/OldBugMove/template/en/default/admin/params/oldbugmove.html.tmpl index ce588b168..6bbd07b7e 100644 --- a/extensions/OldBugMove/template/en/default/admin/params/oldbugmove.html.tmpl +++ b/extensions/OldBugMove/template/en/default/admin/params/oldbugmove.html.tmpl @@ -25,16 +25,16 @@ [% param_descs = { - "move-to-url" => + "move-to-url" => "The URL of the database we allow some of our $terms.bugs to" _ " be moved to.", - "move-to-address" => + "move-to-address" => "To move ${terms.bugs}, an email is sent to the target database." _ " This is the email address that that database uses to listen" _ " for incoming ${terms.bugs}.", - movers => + movers => "A list of people with permission to move $terms.bugs ", } %] diff --git a/extensions/OldBugMove/template/en/default/hook/bug/edit-after_comment_textarea.html.tmpl b/extensions/OldBugMove/template/en/default/hook/bug/edit-after_comment_textarea.html.tmpl index 0a7a4fa27..d55213400 100644 --- a/extensions/OldBugMove/template/en/default/hook/bug/edit-after_comment_textarea.html.tmpl +++ b/extensions/OldBugMove/template/en/default/hook/bug/edit-after_comment_textarea.html.tmpl @@ -21,7 +21,7 @@ [% IF oldbugmove_user_is_mover(user) AND bug.resolution != 'MOVED' %] <p> <input type="submit" id="oldbugmove" name="oldbugmove" - value="Move [% terms.Bug FILTER html %] to + value="Move [% terms.Bug FILTER html %] to [%= Param('move-to-url') FILTER html %]"> </p> [% END %] diff --git a/extensions/OldBugMove/template/en/default/hook/bug/format_comment-type.txt.tmpl b/extensions/OldBugMove/template/en/default/hook/bug/format_comment-type.txt.tmpl index 1ce8e369d..069e55628 100644 --- a/extensions/OldBugMove/template/en/default/hook/bug/format_comment-type.txt.tmpl +++ b/extensions/OldBugMove/template/en/default/hook/bug/format_comment-type.txt.tmpl @@ -24,6 +24,6 @@ [%+ terms.Bug %] moved to [% Param("move-to-url") %]. If the move succeeded, [% comment.extra_data FILTER email %] will receive a mail containing the number of the new [% terms.bug %] in the other database. -If all went well, please paste in a link to the new [% terms.bug %]. +If all went well, please paste in a link to the new [% terms.bug %]. Otherwise, reopen this [% terms.bug %]. [% END %] diff --git a/extensions/OldBugMove/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/OldBugMove/template/en/default/hook/global/user-error-errors.html.tmpl index 935117780..e6f8284ba 100644 --- a/extensions/OldBugMove/template/en/default/hook/global/user-error-errors.html.tmpl +++ b/extensions/OldBugMove/template/en/default/hook/global/user-error-errors.html.tmpl @@ -23,7 +23,7 @@ delete the [%+ display_value("resolution", "MOVED") FILTER html %] resolution. [% ELSIF error == "oldbugmove_no_manual_move" %] - You cannot set the resolution of [% terms.abug %] to + You cannot set the resolution of [% terms.abug %] to [%+ display_value("resolution", "MOVED") FILTER html %] without moving the [% terms.bug %]. [% END %] diff --git a/extensions/OldBugMove/template/en/default/hook/list/edit-multiple-after_groups.html.tmpl b/extensions/OldBugMove/template/en/default/hook/list/edit-multiple-after_groups.html.tmpl index 10e6f73b3..a34392577 100644 --- a/extensions/OldBugMove/template/en/default/hook/list/edit-multiple-after_groups.html.tmpl +++ b/extensions/OldBugMove/template/en/default/hook/list/edit-multiple-after_groups.html.tmpl @@ -22,7 +22,7 @@ [% IF oldbugmove_user_is_mover(user) %] <p> <input type="submit" id="oldbugmove" name="oldbugmove" - value="Move [% terms.Bugs FILTER html %] to + value="Move [% terms.Bugs FILTER html %] to [%= Param('move-to-url') FILTER html %]"> </p> [% END %] diff --git a/extensions/OrangeFactor/web/js/LICENSE.processing.js b/extensions/OrangeFactor/web/js/LICENSE.processing.js index 404e5d5eb..9070bddea 100644 --- a/extensions/OrangeFactor/web/js/LICENSE.processing.js +++ b/extensions/OrangeFactor/web/js/LICENSE.processing.js @@ -5,7 +5,7 @@ copyright holders. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -13,7 +13,7 @@ the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE diff --git a/extensions/OrangeFactor/web/js/LICENSE.sparklines.js b/extensions/OrangeFactor/web/js/LICENSE.sparklines.js index 73aaca832..7c922a477 100644 --- a/extensions/OrangeFactor/web/js/LICENSE.sparklines.js +++ b/extensions/OrangeFactor/web/js/LICENSE.sparklines.js @@ -3,7 +3,7 @@ Copyright (C) 2008 Will Larson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -11,7 +11,7 @@ the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE diff --git a/extensions/OrangeFactor/web/js/orange_factor.js b/extensions/OrangeFactor/web/js/orange_factor.js index 78fbb5eb3..e9383901e 100644 --- a/extensions/OrangeFactor/web/js/orange_factor.js +++ b/extensions/OrangeFactor/web/js/orange_factor.js @@ -3,7 +3,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. * * This Source Code Form is "Incompatible With Secondary Licenses", as - * defined by the Mozilla Public License, v. 2.0. + * defined by the Mozilla Public License, v. 2.0. */ $(function() { diff --git a/extensions/OrangeFactor/web/js/sparklines.min.js b/extensions/OrangeFactor/web/js/sparklines.min.js index f1043c55e..a5fed6326 100644 --- a/extensions/OrangeFactor/web/js/sparklines.min.js +++ b/extensions/OrangeFactor/web/js/sparklines.min.js @@ -1,4 +1,4 @@ -/* Sparklines.js - Will Larson (http://lethain.com) +/* Sparklines.js - Will Larson (http://lethain.com) * This code is distributed under the MIT license. * See LICENSE.sparklines.js * More information: https://github.com/lethain/sparklines.js diff --git a/extensions/Persona/Config.pm b/extensions/Persona/Config.pm deleted file mode 100644 index fa878bb05..000000000 --- a/extensions/Persona/Config.pm +++ /dev/null @@ -1,27 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Extension::Persona; - -use 5.10.1; -use strict; -use warnings; - -use constant NAME => 'Persona'; - -use constant REQUIRED_MODULES => [ - { - package => 'JSON', - module => 'JSON', - version => 0, - }, -]; - -use constant OPTIONAL_MODULES => [ -]; - -__PACKAGE__->NAME; diff --git a/extensions/Persona/Extension.pm b/extensions/Persona/Extension.pm deleted file mode 100644 index f94c54446..000000000 --- a/extensions/Persona/Extension.pm +++ /dev/null @@ -1,86 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Extension::Persona; - -use 5.10.1; -use strict; -use warnings; - -use base qw(Bugzilla::Extension); - -use Bugzilla::Config qw(SetParam write_params); - -our $VERSION = '0.01'; - -sub install_update_db { - # The extension changed from BrowserID to Persona - # so we need to update user_info_class if this system - # was using BrowserID for verification. - my $params = Bugzilla->params || Bugzilla::Config::read_param_file(); - my $user_info_class = $params->{'user_info_class'}; - if ($user_info_class =~ /BrowserID/) { - $user_info_class =~ s/BrowserID/Persona/; - SetParam('user_info_class', $user_info_class); - write_params(); - } -} - -sub auth_login_methods { - my ($self, $args) = @_; - my $modules = $args->{'modules'}; - if (exists($modules->{'Persona'})) { - $modules->{'Persona'} = 'Bugzilla/Extension/Persona/Login.pm'; - } -} - -sub config_modify_panels { - my ($self, $args) = @_; - my $panels = $args->{'panels'}; - my $auth_panel_params = $panels->{'auth'}->{'params'}; - - my ($user_info_class) = - grep { $_->{'name'} eq 'user_info_class' } @$auth_panel_params; - - if ($user_info_class) { - push(@{ $user_info_class->{'choices'} }, "Persona,CGI"); - } - - # The extension changed from BrowserID to Persona - # so we need to retain the current values for the new - # params that will be created. - my $params = Bugzilla->params || Bugzilla::Config::read_param_file(); - my $verify_url = $params->{'browserid_verify_url'}; - my $includejs_url = $params->{'browserid_includejs_url'}; - if ($verify_url && $includejs_url) { - foreach my $param (@{ $panels->{'persona'}->{'params'} }) { - if ($param->{'name'} eq 'persona_verify_url') { - $param->{'default'} = $verify_url; - } - if ($param->{'name'} eq 'persona_includejs_url') { - $param->{'default'} = $includejs_url; - } - } - } -} - -sub attachment_should_redirect_login { - my ($self, $args) = @_; - my $cgi = Bugzilla->cgi; - - if ($cgi->param("persona_assertion")) { - ${$args->{do_redirect}} = 1; - } -} - -sub config_add_panels { - my ($self, $args) = @_; - my $modules = $args->{panel_modules}; - $modules->{Persona} = "Bugzilla::Extension::Persona::Config"; -} - -__PACKAGE__->NAME; diff --git a/extensions/Persona/TODO b/extensions/Persona/TODO deleted file mode 100644 index ac94a3c42..000000000 --- a/extensions/Persona/TODO +++ /dev/null @@ -1,19 +0,0 @@ -ToDo: - -* Cache the LWP::UserAgent in Login.pm? - -* Fix Bugzilla::Auth::Login::Stack to allow failure part way down the chain - (currently, it seems that both CGI and BrowserID have to be last in order - to report login failures correctly.) - -* JS inclusions noticeably slow page load. Do we want a local copy of - browserid.js? Do the browserid folks object to that? How can we get good - performance? How can we avoid including it in every logged-in page? Can we - do demand loading onclick, and/or load-on-reveal? - -* Fix -8px margin-bottom hack in login-small-additional_methods.html.tmpl - - - - - diff --git a/extensions/Persona/lib/Config.pm b/extensions/Persona/lib/Config.pm deleted file mode 100644 index ae40fd94a..000000000 --- a/extensions/Persona/lib/Config.pm +++ /dev/null @@ -1,42 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Extension::Persona::Config; - -use 5.10.1; -use strict; -use warnings; - -use Bugzilla::Config::Common; - -our $sortkey = 1350; - -sub get_param_list { - my ($class) = @_; - - my @param_list = ( - { - name => 'persona_verify_url', - type => 't', - default => 'https://verifier.login.persona.org/verify', - }, - { - name => 'persona_includejs_url', - type => 't', - default => 'https://login.persona.org/include.js', - }, - { - name => 'persona_proxy_url', - type => 't', - default => '', - }, - ); - - return @param_list; -} - -1; diff --git a/extensions/Persona/lib/Login.pm b/extensions/Persona/lib/Login.pm deleted file mode 100644 index 9a5e3a5b7..000000000 --- a/extensions/Persona/lib/Login.pm +++ /dev/null @@ -1,137 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Extension::Persona::Login; - -use 5.10.1; -use strict; -use warnings; - -use base qw(Bugzilla::Auth::Login); - -use Bugzilla::Constants; -use Bugzilla::Util; -use Bugzilla::Error; -use Bugzilla::Token; - -use JSON; -use LWP::UserAgent; - -use constant requires_verification => 0; -use constant is_automatic => 1; -use constant user_can_create_account => 1; - -sub get_login_info { - my ($self) = @_; - - my $cgi = Bugzilla->cgi; - - my $assertion = $cgi->param("persona_assertion"); - # Avoid the assertion being copied into any 'echoes' of the current URL - # in the page. - $cgi->delete('persona_assertion'); - - if (!$assertion || !Bugzilla->params->{persona_verify_url}) { - return { failure => AUTH_NODATA }; - } - - my $token = $cgi->param("token"); - $cgi->delete('token'); - check_hash_token($token, ['login']); - - my $urlbase = new URI(Bugzilla->localconfig->{urlbase}); - my $audience = $urlbase->scheme . "://" . $urlbase->host_port; - - my $ua = new LWP::UserAgent( timeout => 10 ); - if (Bugzilla->params->{persona_proxy_url}) { - $ua->proxy('https', Bugzilla->params->{persona_proxy_url}); - } - - my $response = $ua->post(Bugzilla->params->{persona_verify_url}, - [ assertion => $assertion, - audience => $audience ]); - if ($response->is_error) { - return { failure => AUTH_ERROR, - user_error => 'persona_server_fail', - details => { reason => $response->message }}; - } - - my $info; - eval { - $info = decode_json($response->decoded_content()); - }; - if ($@) { - return { failure => AUTH_ERROR, - user_error => 'persona_server_fail', - details => { reason => 'Received a malformed response.' }}; - } - if ($info->{'status'} eq 'failure') { - return { failure => AUTH_ERROR, - user_error => 'persona_server_fail', - details => { reason => $info->{reason} }}; - } - - if ($info->{'status'} eq "okay" && - $info->{'audience'} eq $audience && - ($info->{'expires'} / 1000) > time()) - { - my $login_data = { - 'username' => $info->{'email'} - }; - - my $result = Bugzilla::Auth::Verify->create_or_update_user($login_data); - return $result if $result->{'failure'}; - - my $user = $result->{'user'}; - - # You can restrict people in a particular group from logging in using - # Persona by making that group a member of a group called - # "no-browser-id". - # - # If you have your "createemailregexp" set up in such a way that a - # newly-created account is a member of "no-browser-id", this code will - # create an account for them and then fail their login. Which isn't - # great, but they can still use normal-Bugzilla-login password - # recovery. - if ($user->in_group('no-browser-id')) { - return { failure => AUTH_ERROR, - user_error => 'persona_account_too_powerful' }; - } - - if ($user->mfa) { - return { failure => AUTH_ERROR, - user_error => 'mfa_prevents_login', - details => { provider => 'Persona' } }; - } - - $login_data->{'user'} = $user; - $login_data->{'user_id'} = $user->id; - - return $login_data; - } - else { - return { failure => AUTH_LOGINFAILED }; - } -} - -# Pinched from Bugzilla::Auth::Login::CGI -sub fail_nodata { - my ($self) = @_; - my $cgi = Bugzilla->cgi; - my $template = Bugzilla->template; - - if (Bugzilla->usage_mode != USAGE_MODE_BROWSER) { - ThrowUserError('login_required'); - } - - print $cgi->header(); - $template->process("account/auth/login.html.tmpl", { 'target' => $cgi->url(-relative=>1) }) - || ThrowTemplateError($template->error()); - exit; -} - -1; diff --git a/extensions/Persona/template/en/default/admin/params/browserid.html.tmpl b/extensions/Persona/template/en/default/admin/params/browserid.html.tmpl deleted file mode 100644 index 379d12058..000000000 --- a/extensions/Persona/template/en/default/admin/params/browserid.html.tmpl +++ /dev/null @@ -1,22 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% - title = "Persona" - desc = "Configure Persona Authentication" -%] - -[% param_descs = { - persona_verify_url => "This is the URL for the Persona authority that the " _ - "user will be verified against. " _ - "Example: <kbd>https://verifier.login.persona.org/verify</kbd>.", - persona_includejs_url => "This is the URL needed by Persona to load the necessary " _ - "javascript library for authentication. " _ - "Example: <kbd>https://persona.org/include.js</kbd>." - } -%] diff --git a/extensions/Persona/template/en/default/admin/params/persona.html.tmpl b/extensions/Persona/template/en/default/admin/params/persona.html.tmpl deleted file mode 100644 index ef3cf32d2..000000000 --- a/extensions/Persona/template/en/default/admin/params/persona.html.tmpl +++ /dev/null @@ -1,24 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% - title = "Persona" - desc = "Configure Persona Authentication" -%] - -[% param_descs = { - persona_verify_url => "This is the URL for the Persona authority that the " _ - "user will be verified against. " _ - "Example: <kbd>https://verifier.login.persona.org/verify</kbd>.", - persona_includejs_url => "This is the URL needed by Persona to load the necessary " _ - "javascript library for authentication. " _ - "Example: <kbd>https://login.persona.org/include.js</kbd>." - persona_proxy_url => "The URL of a HTTPS proxy server (optional). " _ - "Example: <kbd>http://proxy.example.com:3128</kbd>." - } -%] diff --git a/extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl b/extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl deleted file mode 100644 index 1743db9a6..000000000 --- a/extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl +++ /dev/null @@ -1,9 +0,0 @@ -[% IF Param('user_info_class').split(',').contains('Persona') - && Param('persona_includejs_url') %] -<p> - <img src="extensions/Persona/web/images/persona_sign_in.png" width="185" height="25" class="persona_sign_in"> -</p> -<p> - <strong>Note:</strong> Persona authentication will be removed on October 25th, 2016 (<a href="page.cgi?id=persona_deprecated.html">more info</a>). -</p> -[% END %] diff --git a/extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl b/extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl deleted file mode 100644 index 364d1528f..000000000 --- a/extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl +++ /dev/null @@ -1,17 +0,0 @@ -[% IF Param('user_info_class').split(',').contains('Persona') - && Param('persona_includejs_url') %] -<script [% script_nonce FILTER none %]> - YAHOO.util.Event.addListener('login_link[% qs_suffix FILTER js %]','click', function () { - var login_link = YAHOO.util.Dom.get('persona_mini_login[% qs_suffix FILTER js %]'); - YAHOO.util.Dom.removeClass(login_link, 'bz_default_hidden'); - }); - YAHOO.util.Event.addListener('hide_mini_login[% qs_suffix FILTER js %]','click', function () { - var login_link = YAHOO.util.Dom.get('persona_mini_login[% qs_suffix FILTER js %]'); - YAHOO.util.Dom.addClass(login_link, 'bz_default_hidden'); - }); -</script> -<span id="persona_mini_login[% qs_suffix FILTER html %]" class="bz_default_hidden"> - <img src="extensions/Persona/web/images/sign_in.png" height="22" width="75" align="absmiddle" - title="Sign in with Persona" class='persona_sign_in'> or -</span> -[% END %] diff --git a/extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl b/extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl deleted file mode 100644 index b6fb1eedc..000000000 --- a/extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl +++ /dev/null @@ -1,13 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% RETURN UNLESS Param('user_info_class').split(',').contains('Persona') %] - -Or, use your Persona account: -<img src="extensions/Persona/web/images/sign_in.png" class="persona_sign_in" - width="95" height="25" align="absmiddle"> diff --git a/extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl b/extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl deleted file mode 100644 index f60bd36db..000000000 --- a/extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl +++ /dev/null @@ -1,90 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% RETURN UNLESS Param('persona_includejs_url') - && Param('user_info_class').split(',').contains('Persona') %] - -[%# for now don't inject persona javascript on authenticated users. - # we've seen sessions being logged out unexpectedly - # we should only inject this code for users who used persona to authenicate %] -[% RETURN IF user.id %] - -[% USE Bugzilla %] -[% cgi = Bugzilla.cgi %] - -<script [% script_nonce FILTER none %] defer src="[% Param('persona_includejs_url') %]"></script> -<script [% script_nonce FILTER none %]> - -function createHidden(name, value, form) { - var field = document.createElement('input'); - field.type = 'hidden'; - field.name = name; - field.value = value;; - form.appendChild(field); -} - -[% login_target = cgi.url("-relative" => 1, "-query" => 1) %] -[% IF !login_target - OR login_target.match("^token\.cgi") - OR login_target.match("^createaccount\.cgi") %] - [% login_target = "index.cgi" %] -[% END %] -[% login_target = urlbase _ login_target %] - -[%# we only want to honour explicit login requests %] -var persona_ignore_login = true; - -function persona_onlogin(assertion) { - if (persona_ignore_login) - return; - [% IF !user.id %] - var form = document.createElement('form'); - form.action = '[% login_target FILTER js %]'; - form.method = 'POST'; - form.style.display = 'none'; - - createHidden('token', '[% issue_hash_token(['login']) FILTER js %]', form); - createHidden('Bugzilla_remember', 'on', form); - createHidden('persona_assertion', assertion, form); - - [% FOREACH field = cgi.param() %] - [% NEXT IF field.search('^(Bugzilla_(login|password|restrictlogin)|token|persona_assertion)$') %] - [% NEXT UNLESS cgi.param(field).can('slice') %] - [% FOREACH mvalue = cgi.param(field).slice(0) %] - createHidden('[% field FILTER js %]', '[% mvalue FILTER html_linebreak FILTER js %]', form); - [% END %] - [% END %] - - document.body.appendChild(form); - form.submit(); - [% END %] -} - -YAHOO.util.Event.on(window, 'load', persona_init); -function persona_init() { - navigator.id.watch({ - [%# we can't set loggedInUser to user.login as this causes cgi authenticated - sessions to be logged out by persona %] - loggedInUser: null, - onlogin: persona_onlogin, - onlogout: function () { - [%# this should be redirecting to index.cgi?logout=1 however there's a - persona bug which causes this to break chrome and safari logins. - https://github.com/mozilla/browserid/issues/2423 %] - } - }); -} - -function persona_sign_in() { - persona_ignore_login = false; - navigator.id.request({ siteName: '[% terms.BugzillaTitle FILTER js %]' }); -} -$(function() { - $('.persona_sign_in').on("click", persona_sign_in); -}); -</script> diff --git a/extensions/Persona/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/Persona/template/en/default/hook/global/user-error-errors.html.tmpl deleted file mode 100644 index f2e5bda24..000000000 --- a/extensions/Persona/template/en/default/hook/global/user-error-errors.html.tmpl +++ /dev/null @@ -1,12 +0,0 @@ -[% IF error == "persona_account_too_powerful" %] - [% title = "Account Too Powerful" %] - Your account is a member of a group which is not permitted to use Persona to - log in. Please log in with your [% terms.Bugzilla %] username and password. - <br><br> - (Persona logins are disabled for accounts which are members of certain - particularly sensitive groups, while we gain experience with the technology.) -[% ELSIF error == "persona_server_fail" %] - An error occurred during communication with the Persona servers: - <br> - [% reason FILTER html %] -[% END %] diff --git a/extensions/Persona/web/images/persona_sign_in.png b/extensions/Persona/web/images/persona_sign_in.png Binary files differdeleted file mode 100644 index ab88a7154..000000000 --- a/extensions/Persona/web/images/persona_sign_in.png +++ /dev/null diff --git a/extensions/Persona/web/images/sign_in.png b/extensions/Persona/web/images/sign_in.png Binary files differdeleted file mode 100644 index 82594ba82..000000000 --- a/extensions/Persona/web/images/sign_in.png +++ /dev/null diff --git a/extensions/PhabBugz/lib/Constants.pm b/extensions/PhabBugz/lib/Constants.pm index 1692f8fb9..19987de25 100644 --- a/extensions/PhabBugz/lib/Constants.pm +++ b/extensions/PhabBugz/lib/Constants.pm @@ -19,6 +19,7 @@ our @EXPORT = qw( PHAB_FEED_POLL_SECONDS PHAB_USER_POLL_SECONDS PHAB_GROUP_POLL_SECONDS + PHAB_TIMEOUT ); use constant PHAB_ATTACHMENT_PATTERN => qr/^phabricator-D(\d+)/; @@ -27,5 +28,6 @@ use constant PHAB_CONTENT_TYPE => 'text/x-phabricator-request'; use constant PHAB_FEED_POLL_SECONDS => $ENV{PHAB_FEED_POLL} // 5; use constant PHAB_USER_POLL_SECONDS => $ENV{PHAB_USER_POLL} // 60; use constant PHAB_GROUP_POLL_SECONDS => $ENV{PHAB_GROUP_POLL} // 300; +use constant PHAB_TIMEOUT => $ENV{PHAB_TIMEOUT} // 60; 1; diff --git a/extensions/PhabBugz/lib/Feed.pm b/extensions/PhabBugz/lib/Feed.pm index f2a440bb1..71e6aa827 100644 --- a/extensions/PhabBugz/lib/Feed.pm +++ b/extensions/PhabBugz/lib/Feed.pm @@ -11,10 +11,10 @@ use 5.10.1; use IO::Async::Timer::Periodic; use IO::Async::Loop; +use IO::Async::Signal; use List::Util qw(first); use List::MoreUtils qw(any uniq); use Moo; -use Scalar::Util qw(blessed); use Try::Tiny; use Type::Params qw( compile ); use Type::Utils; @@ -48,6 +48,13 @@ my $Invocant = class_type { class => __PACKAGE__ }; sub start { my ($self) = @_; + my $sig_alarm = IO::Async::Signal->new( + name => 'ALRM', + on_receipt => sub { + FATAL("Timeout reached"); + exit; + }, + ); # Query for new revisions or changes my $feed_timer = IO::Async::Timer::Periodic->new( first_interval => 0, @@ -56,13 +63,17 @@ sub start { on_tick => sub { try { with_writable_database { + alarm(PHAB_TIMEOUT); $self->feed_query(); }; } catch { FATAL($_); + } + finally { + alarm(0); + Bugzilla->_cleanup(); }; - Bugzilla->_cleanup(); }, ); @@ -74,13 +85,17 @@ sub start { on_tick => sub { try { with_writable_database { + alarm(PHAB_TIMEOUT); $self->user_query(); }; } catch { FATAL($_); + } + finally { + alarm(0); + Bugzilla->_cleanup(); }; - Bugzilla->_cleanup(); }, ); @@ -92,13 +107,18 @@ sub start { on_tick => sub { try { with_writable_database { + alarm(PHAB_TIMEOUT); $self->group_query(); }; } catch { FATAL($_); + } + finally { + alarm(0); + Bugzilla->_cleanup(); }; - Bugzilla->_cleanup(); + }, ); @@ -106,6 +126,7 @@ sub start { $loop->add($feed_timer); $loop->add($user_timer); $loop->add($group_timer); + $loop->add($sig_alarm); $feed_timer->start; $user_timer->start; $group_timer->start; @@ -221,6 +242,11 @@ sub feed_query { $delete_build_target->execute($target->{name}, $target->{value}); } + + if (Bugzilla->datadog) { + my $dd = Bugzilla->datadog(); + $dd->increment('bugzilla.phabbugz.feed_query_count'); + } } sub user_query { @@ -261,6 +287,11 @@ sub user_query { }; $self->save_last_id($user_id, 'user'); } + + if (Bugzilla->datadog) { + my $dd = Bugzilla->datadog(); + $dd->increment('bugzilla.phabbugz.user_query_count'); + } } sub group_query { @@ -359,6 +390,11 @@ sub group_query { INFO( "Project " . $project->name . " updated" ); } } + + if (Bugzilla->datadog) { + my $dd = Bugzilla->datadog(); + $dd->increment('bugzilla.phabbugz.group_query_count'); + } } sub process_revision_change { @@ -501,105 +537,6 @@ sub process_revision_change { $attachment->update($timestamp); } - # REVIEWER STATUSES - - my (@accepted, @denied); - foreach my $review (@{ $revision->reviews }) { - push @accepted, $review->{user} if $review->{status} eq 'accepted'; - push @denied, $review->{user} if $review->{status} eq 'rejected'; - } - - my @accepted_user_ids = map { $_->bugzilla_user->id } grep { defined $_->bugzilla_user } @accepted; - my @denied_user_ids = map { $_->bugzilla_user->id } grep { defined $_->bugzilla_user } @denied; - my %reviewers_hash = map { $_->{user}->name => 1 } @{ $revision->reviews }; - - foreach my $attachment (@attachments) { - my ($attach_revision_id) = ($attachment->filename =~ PHAB_ATTACHMENT_PATTERN); - next if $revision->id != $attach_revision_id; - - # Clear old accepted review flags if no longer accepted - my (@denied_flags, @new_flags, @removed_flags, %accepted_done, $flag_type); - foreach my $flag (@{ $attachment->flags }) { - next if $flag->type->name ne 'review'; - $flag_type = $flag->type if $flag->type->is_active; - next if $flag->status ne '+'; - if (any { $flag->setter->id == $_ } @denied_user_ids) { - INFO('Denying review flag set by ' . $flag->setter->name); - push(@denied_flags, { id => $flag->id, setter => $flag->setter, status => 'X' }); - } - if (any { $flag->setter->id == $_ } @accepted_user_ids) { - INFO('Skipping as review+ already set by ' . $flag->setter->name); - $accepted_done{$flag->setter->id}++; - } - if (!any { $flag->setter->id == $_ } (@accepted_user_ids, @denied_user_ids)) { - INFO('Clearing review+ flag set by ' . $flag->setter->name); - push(@removed_flags, { id => $flag->id, setter => $flag->setter, status => 'X' }); - } - } - - $flag_type ||= first { $_->name eq 'review' && $_->is_active } @{ $attachment->flag_types }; - - die "Unable to find review flag!" unless $flag_type; - - # Create new flags - foreach my $user_id (@accepted_user_ids) { - next if $accepted_done{$user_id}; - my $user = Bugzilla::User->check({ id => $user_id, cache => 1 }); - INFO('Setting new review+ flag for ' . $user->name); - push(@new_flags, { type_id => $flag_type->id, setter => $user, status => '+' }); - } - - # Process each flag change by updating the flag and adding a comment - foreach my $flag_data (@new_flags) { - my $comment = $flag_data->{setter}->name . " has approved the revision."; - $self->add_flag_comment( - { - bug => $bug, - attachment => $attachment, - comment => $comment, - user => $flag_data->{setter}, - old_flags => [], - new_flags => [$flag_data], - timestamp => $timestamp - } - ); - } - foreach my $flag_data (@denied_flags) { - my $comment = $flag_data->{setter}->name . " has requested changes to the revision.\n"; - $self->add_flag_comment( - { - bug => $bug, - attachment => $attachment, - comment => $comment, - user => $flag_data->{setter}, - old_flags => [$flag_data], - new_flags => [], - timestamp => $timestamp - } - ); - } - foreach my $flag_data (@removed_flags) { - my $comment; - if ( exists $reviewers_hash{ $flag_data->{setter}->name } ) { - $comment = "Flag set by " . $flag_data->{setter}->name . " is no longer active.\n"; - } - else { - $comment = $flag_data->{setter}->name . " has been removed from the revision.\n"; - } - $self->add_flag_comment( - { - bug => $bug, - attachment => $attachment, - comment => $comment, - user => $flag_data->{setter}, - old_flags => [$flag_data], - new_flags => [], - timestamp => $timestamp - } - ); - } - } - # FINISH UP $bug->update($timestamp); @@ -736,6 +673,11 @@ sub process_new_user { foreach my $attachment (@attachments) { my ($revision_id) = ($attachment->filename =~ PHAB_ATTACHMENT_PATTERN); + if (!$revision_id) { + WARN("Skipping " . $attachment->filename . " on bug $bug_id. Filename should be fixed."); + next; + } + INFO("Processing revision D$revision_id"); my $revision = Bugzilla::Extension::PhabBugz::Revision->new_from_query( @@ -839,38 +781,4 @@ sub get_group_members { ); } -sub add_flag_comment { - state $check = compile( - $Invocant, - Dict [ - bug => Bug, - attachment => Attachment, - comment => Str, - user => User, - old_flags => ArrayRef, - new_flags => ArrayRef, - timestamp => Str, - ], - ); - my ( $self, $params ) = $check->(@_); - my ( $bug, $attachment, $comment, $user, $old_flags, $new_flags, $timestamp ) - = @$params{qw(bug attachment comment user old_flags new_flags timestamp)}; - - # when this function returns, Bugzilla->user will return to its previous value. - my $restore_prev_user = Bugzilla->set_user($user, scope_guard => 1); - - INFO("Flag comment: $comment"); - $bug->add_comment( - $comment, - { - isprivate => $attachment->isprivate, - type => CMT_ATTACHMENT_UPDATED, - extra_data => $attachment->id - } - ); - - $attachment->set_flags( $old_flags, $new_flags ); - $attachment->update($timestamp); -} - 1; diff --git a/extensions/PhabBugz/lib/Util.pm b/extensions/PhabBugz/lib/Util.pm index a93533e75..32f860413 100644 --- a/extensions/PhabBugz/lib/Util.pm +++ b/extensions/PhabBugz/lib/Util.pm @@ -20,14 +20,14 @@ use Bugzilla::Util qw(trim); use Bugzilla::Extension::PhabBugz::Constants; use Bugzilla::Extension::PhabBugz::Types qw(:types); -use JSON::XS qw(encode_json decode_json); use List::Util qw(first); -use LWP::UserAgent; use Taint::Util qw(untaint); use Try::Tiny; use Type::Params qw( compile ); use Type::Utils; use Types::Standard qw( :types ); +use Mojo::UserAgent; +use Mojo::JSON qw(encode_json); use base qw(Exporter); @@ -35,7 +35,6 @@ our @EXPORT = qw( create_revision_attachment get_attachment_revisions get_bug_role_phids - get_needs_review intersect is_attachment_phab_revision request @@ -160,11 +159,10 @@ sub request { my $ua = $request_cache->{phabricator_ua}; unless ($ua) { - $ua = $request_cache->{phabricator_ua} = LWP::UserAgent->new(timeout => 10); + $ua = $request_cache->{phabricator_ua} = Mojo::UserAgent->new; if ($params->{proxy_url}) { - $ua->proxy('https', $params->{proxy_url}); + $ua->proxy($params->{proxy_url}); } - $ua->default_header('Content-Type' => 'application/x-www-form-urlencoded'); } my $phab_api_key = $params->{phabricator_api_key}; @@ -176,25 +174,16 @@ sub request { $data->{__conduit__} = { token => $phab_api_key }; - my $response = $ua->post($full_uri, { params => encode_json($data) }); - + my $response = $ua->post($full_uri => form => { params => encode_json($data) })->result; ThrowCodeError('phabricator_api_error', { reason => $response->message }) if $response->is_error; - my $result; - my $result_ok = eval { - my $content = $response->content; - untaint($content); - $result = decode_json( $content ); - 1; - }; - if (!$result_ok || $result->{error_code}) { - ThrowCodeError('phabricator_api_error', - { reason => 'JSON decode failure' }) if !$result_ok; - ThrowCodeError('phabricator_api_error', - { code => $result->{error_code}, - reason => $result->{error_info} }) if $result->{error_code}; - } + my $result = $response->json; + ThrowCodeError('phabricator_api_error', + { reason => 'JSON decode failure' }) if !defined($result); + ThrowCodeError('phabricator_api_error', + { code => $result->{error_code}, + reason => $result->{error_info} }) if $result->{error_code}; return $result; } @@ -206,48 +195,4 @@ sub set_phab_user { return Bugzilla->set_user($user, scope_guard => 1); } -sub get_needs_review { - my ($user) = @_; - $user //= Bugzilla->user; - return unless $user->id; - - my $phab_user = Bugzilla::Extension::PhabBugz::User->new_from_query( - { - ids => [ $user->id ] - } - ); - - return [] unless $phab_user; - - my $diffs = request( - 'differential.revision.search', - { - attachments => { - reviewers => 1, - }, - constraints => { - reviewerPHIDs => [$phab_user->phid], - statuses => ["open()"], - }, - order => 'newest', - } - ); - ThrowCodeError('phabricator_api_error', { reason => 'Malformed Response' }) - unless exists $diffs->{result}{data}; - - my @revisions; - foreach my $revision ( @{ $diffs->{result}{data} } ) { - foreach my $reviewer ( @{ $revision->{attachments}->{reviewers}->{reviewers} } ) { - if ( $reviewer->{reviewerPHID} eq $phab_user->phid - && $reviewer->{status} =~ /^(?:added|blocking)$/ ) - { - push @revisions, $revision; - last; - } - } - } - - return \@revisions; -} - 1; diff --git a/extensions/PhabBugz/lib/WebService.pm b/extensions/PhabBugz/lib/WebService.pm index fa9306667..19a758a70 100644 --- a/extensions/PhabBugz/lib/WebService.pm +++ b/extensions/PhabBugz/lib/WebService.pm @@ -16,29 +16,23 @@ use base qw(Bugzilla::WebService); use Bugzilla::Constants; use Bugzilla::Error; use Bugzilla::User; -use Bugzilla::Util qw(detaint_natural datetime_from time_ago trick_taint); +use Bugzilla::Util qw(detaint_natural trick_taint); use Bugzilla::WebService::Constants; use Bugzilla::Extension::PhabBugz::Constants; -use Bugzilla::Extension::PhabBugz::Util qw( - get_needs_review -); -use DateTime (); -use List::Util qw(first uniq); +use List::Util qw(first); use List::MoreUtils qw(any); use MIME::Base64 qw(decode_base64); use constant READ_ONLY => qw( check_user_enter_bug_permission check_user_permission_for_bug - needs_review ); use constant PUBLIC_METHODS => qw( check_user_enter_bug_permission check_user_permission_for_bug - needs_review set_build_target ); @@ -99,95 +93,6 @@ sub check_user_enter_bug_permission { }; } -sub needs_review { - my ($self, $params) = @_; - - $self->_check_phabricator(); - - my $user = Bugzilla->login(LOGIN_REQUIRED); - my $dbh = Bugzilla->dbh; - - my $reviews = get_needs_review(); - - my $authors = Bugzilla::Extension::PhabBugz::User->match({ - phids => [ - uniq - grep { defined } - map { $_->{fields}{authorPHID} } - @$reviews - ] - }); - - my %author_phab_to_id = map { $_->phid => $_->bugzilla_user->id } @$authors; - my %author_id_to_user = map { $_->bugzilla_user->id => $_->bugzilla_user } @$authors; - - # bug data - my $visible_bugs = $user->visible_bugs([ - uniq - grep { $_ } - map { $_->{fields}{'bugzilla.bug-id'} } - @$reviews - ]); - - # get all bug statuses and summaries in a single query to avoid creation of - # many bug objects - my %bugs; - if (@$visible_bugs) { - #<<< - my $bug_rows =$dbh->selectall_arrayref( - 'SELECT bug_id, bug_status, short_desc ' . - ' FROM bugs ' . - ' WHERE bug_id IN (' . join(',', ('?') x @$visible_bugs) . ')', - { Slice => {} }, - @$visible_bugs - ); - #>>> - %bugs = map { $_->{bug_id} => $_ } @$bug_rows; - } - - # build result - my $datetime_now = DateTime->now(time_zone => $user->timezone); - my @result; - foreach my $review (@$reviews) { - my $review_flat = { - id => $review->{id}, - title => $review->{fields}{title}, - url => Bugzilla->params->{phabricator_base_uri} . 'D' . $review->{id}, - }; - - # show date in user's timezone - my $datetime = DateTime->from_epoch( - epoch => $review->{fields}{dateModified}, - time_zone => 'UTC' - ); - $datetime->set_time_zone($user->timezone); - $review_flat->{updated} = $datetime->strftime('%Y-%m-%d %T %Z'); - $review_flat->{updated_fancy} = time_ago($datetime, $datetime_now); - - # review requester - if (my $author = $author_id_to_user{$author_phab_to_id{ $review->{fields}{authorPHID} }}) { - $review_flat->{author_name} = $author->name; - $review_flat->{author_email} = $author->email; - } - else { - $review_flat->{author_name} = 'anonymous'; - $review_flat->{author_email} = 'anonymous'; - } - - # referenced bug - if (my $bug_id = $review->{fields}{'bugzilla.bug-id'}) { - my $bug = $bugs{$bug_id}; - $review_flat->{bug_id} = $bug_id; - $review_flat->{bug_status} = $bug->{bug_status}; - $review_flat->{bug_summary} = $bug->{short_desc}; - } - - push @result, $review_flat; - } - - return { result => \@result }; -} - sub set_build_target { my ( $self, $params ) = @_; @@ -257,12 +162,6 @@ sub rest_resources { }, }, }, - # Review requests - qw{^/phabbugz/needs_review$}, { - GET => { - method => 'needs_review', - }, - } ]; } diff --git a/extensions/PhabBugz/t/basic.t b/extensions/PhabBugz/t/basic.t index 9a6723ccb..af92dc64f 100644 --- a/extensions/PhabBugz/t/basic.t +++ b/extensions/PhabBugz/t/basic.t @@ -17,6 +17,7 @@ use Test::More; use Test2::Tools::Mock; use Data::Dumper; use JSON::MaybeXS; +use Bugzilla::Test::Util qw(mock_useragent_tx); use Carp; use Try::Tiny; @@ -98,13 +99,13 @@ my $feed = Bugzilla::Extension::PhabBugz::Feed->new; # Same members in both do { - my $UserAgent = mock 'LWP::UserAgent' => ( + my $UserAgent = mock 'Mojo::UserAgent' => ( override => [ 'post' => sub { - my ($self, $url, $params) = @_; + my ($self, $url, undef, $params) = @_; my $data = decode_json($params->{params}); is_deeply($data->{transactions}, [], 'no-op'); - return mock({is_error => 0, content => '{}'}); + return mock_useragent_tx('{}'); }, ], ); @@ -119,14 +120,14 @@ do { # Project has members not in group do { - my $UserAgent = mock 'LWP::UserAgent' => ( + my $UserAgent = mock 'Mojo::UserAgent' => ( override => [ 'post' => sub { - my ($self, $url, $params) = @_; + my ($self, $url, undef, $params) = @_; my $data = decode_json($params->{params}); my $expected = [ { type => 'members.remove', value => ['foo'] } ]; is_deeply($data->{transactions}, $expected, 'remove foo'); - return mock({is_error => 0, content => '{}'}); + return mock_useragent_tx('{}'); }, ] ); @@ -139,14 +140,14 @@ do { # Group has members not in project do { - my $UserAgent = mock 'LWP::UserAgent' => ( + my $UserAgent = mock 'Mojo::UserAgent' => ( override => [ 'post' => sub { - my ($self, $url, $params) = @_; + my ($self, $url, undef, $params) = @_; my $data = decode_json($params->{params}); my $expected = [ { type => 'members.add', value => ['foo'] } ]; is_deeply($data->{transactions}, $expected, 'add foo'); - return mock({is_error => 0, content => '{}'}); + return mock_useragent_tx('{}'); }, ] ); @@ -164,10 +165,10 @@ do { 'update' => sub { 1 }, ], ); - my $UserAgent = mock 'LWP::UserAgent' => ( + my $UserAgent = mock 'Mojo::UserAgent' => ( override => [ 'post' => sub { - my ($self, $url, $params) = @_; + my ($self, $url, undef, $params) = @_; if ($url =~ /differential\.revision\.search/) { my $content = <<JSON; { @@ -215,10 +216,10 @@ do { } } JSON - return mock { is_error => 0, content => $content }; + return mock_useragent_tx($content); } else { - return mock { is_error => 1, message => "bad request" }; + return mock_useragent_tx("bad request"); } }, ], diff --git a/extensions/PhabBugz/t/feed-daemon-guts.t b/extensions/PhabBugz/t/feed-daemon-guts.t index 376af18e4..0c508be98 100644 --- a/extensions/PhabBugz/t/feed-daemon-guts.t +++ b/extensions/PhabBugz/t/feed-daemon-guts.t @@ -12,7 +12,7 @@ use lib qw( . lib local/lib/perl5 ); BEGIN { $ENV{LOG4PERL_CONFIG_FILE} = 'log4perl-t.conf' } use Bugzilla::Test::MockDB; use Bugzilla::Test::MockParams; -use Bugzilla::Test::Util qw(create_user); +use Bugzilla::Test::Util qw(create_user mock_useragent_tx); use Test::More; use Test2::Tools::Mock; use Try::Tiny; @@ -31,7 +31,7 @@ Bugzilla->error_mode(ERROR_MODE_TEST); my $phab_bot = create_user(PHAB_AUTOMATION_USER, '*'); -my $UserAgent = mock 'LWP::UserAgent' => (); +my $UserAgent = mock 'Mojo::UserAgent' => (); { SetParam('phabricator_enabled', 0); @@ -54,9 +54,9 @@ my $UserAgent = mock 'LWP::UserAgent' => (); } my @bad_response = ( - ['http error', mock({ is_error => 1, message => 'some http error' }) ], - ['invalid json', mock({ is_error => 0, content => '<xml>foo</xml>' })], - ['json containing error code', mock({ is_error => 0, content => encode_json({error_code => 1234 }) })], + ['http error', mock_useragent_tx("doesn't matter", sub { $_->code(500) }) ], + ['invalid json', mock_useragent_tx('<xml>foo</xml>') ], + ['json containing error code', mock_useragent_tx(encode_json({error_code => 1234 }))], ); SetParam(phabricator_enabled => 1); @@ -67,7 +67,7 @@ foreach my $bad_response (@bad_response) { my $feed = Bugzilla::Extension::PhabBugz::Feed->new; $UserAgent->override( post => sub { - my ( $self, $url, $params ) = @_; + my ( $self, $url, undef, $params ) = @_; return $bad_response->[1]; } ); diff --git a/extensions/Profanivore/README b/extensions/Profanivore/README index 5ccab103f..86d46a2a3 100644 --- a/extensions/Profanivore/README +++ b/extensions/Profanivore/README @@ -1,14 +1,14 @@ -Profanivore 'eats' English profanities in comments, leaving behind instead a -trail of droppings ('****'). It finds its food using a standard library Perl -regexp. The profanity is only eaten where the comment was written by a user -who does not have the global 'editbugs' privilege. The digestion happens at +Profanivore 'eats' English profanities in comments, leaving behind instead a +trail of droppings ('****'). It finds its food using a standard library Perl +regexp. The profanity is only eaten where the comment was written by a user +who does not have the global 'editbugs' privilege. The digestion happens at display time, so the comment in the database is unaltered. -However, it does not eat profanities when showing people their own comments; -the aim here is to prevent people immediately noticing they are being +However, it does not eat profanities when showing people their own comments; +the aim here is to prevent people immediately noticing they are being censored, and getting 'creative'. -The purpose of Profanivore is to make it a little harder for trolls to +The purpose of Profanivore is to make it a little harder for trolls to vandalise public Bugzilla installations. It does not currently affect fields other than comments. diff --git a/extensions/Push/lib/Connector/ReviewBoard.pm b/extensions/Push/lib/Connector/ReviewBoard.pm deleted file mode 100644 index 1c657a728..000000000 --- a/extensions/Push/lib/Connector/ReviewBoard.pm +++ /dev/null @@ -1,178 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Extension::Push::Connector::ReviewBoard; - -use 5.10.1; -use strict; -use warnings; - -use base 'Bugzilla::Extension::Push::Connector::Base'; - -use Bugzilla::Bug; -use Bugzilla::BugMail; -use Bugzilla::Component; -use Bugzilla::Constants; -use Bugzilla::Extension::Push::Constants; -use Bugzilla::Extension::Push::Util; -use Bugzilla::Group; -use Bugzilla::Product; -use Bugzilla::User; -use Bugzilla::Util qw( trim ); - -use constant RB_CONTENT_TYPE => 'text/x-review-board-request'; -use constant AUTOMATION_USER => 'automation@bmo.tld'; - -sub options { - return ( - { - name => 'product', - label => 'Product to create bugs in', - type => 'string', - default => 'Developer Services', - required => 1, - validate => sub { - Bugzilla::Product->new({ name => $_[0] }) - || die "Invalid Product ($_[0])\n"; - }, - }, - { - name => 'component', - label => 'Component to create bugs in', - type => 'string', - default => 'MozReview', - required => 1, - validate => sub { - my ($component, $config) = @_; - my $product = Bugzilla::Product->new({ name => $config->{product} }) - || die "Invalid Product (" . $config->{product} . ")\n"; - Bugzilla::Component->new({ product => $product, name => $component }) - || die "Invalid Component ($component)\n"; - }, - }, - { - name => 'version', - label => "The bug's version", - type => 'string', - default => 'Production', - required => 1, - validate => sub { - my ($version, $config) = @_; - my $product = Bugzilla::Product->new({ name => $config->{product} }) - || die "Invalid Product (" . $config->{product} . ")\n"; - Bugzilla::Version->new({ product => $product, name => $version }) - || die "Invalid Version ($version)\n"; - }, - }, - { - name => 'group', - label => 'Security group', - type => 'string', - default => 'mozilla-employee-confidential', - required => 1, - validate => sub { - Bugzilla::Group->new({ name => $_[0] }) - || die "Invalid Group ($_[0])\n"; - }, - }, - { - name => 'cc', - label => 'Comma separated list of users to CC', - type => 'string', - default => '', - required => 1, - validate => sub { - foreach my $login (map { trim($_) } split(',', $_[0])) { - Bugzilla::User->new({ name => $login }) - || die "Invalid User ($login)\n"; - } - }, - }, - ); -} - -sub should_send { - my ($self, $message) = @_; - - if ($message->routing_key =~ /^(?:attachment|bug)\.modify:.*\bis_private\b/) { - my $payload = $message->payload_decoded(); - my $target = $payload->{event}->{target}; - - if ($target ne 'bug' && exists $payload->{$target}->{bug}) { - return 0 if $payload->{$target}->{bug}->{is_private}; - return 0 if $payload->{$target}->{content_type} ne RB_CONTENT_TYPE; - } - - return $payload->{$target}->{is_private} ? 1 : 0; - } - else { - # We're not interested in the message. - return 0; - } -} - -sub send { - my ($self, $message) = @_; - my $logger = Bugzilla->push_ext->logger; - my $config = $self->config; - - eval { - my $payload = $message->payload_decoded(); - my $target = $payload->{event}->{target}; - - # load attachments - my $bug_id = $target eq 'bug' ? $payload->{bug}->{id} : $payload->{attachment}->{bug}->{id}; - my $attach_id = $target eq 'attachment' ? $payload->{attachment}->{id} : undef; - Bugzilla->set_user(Bugzilla::User->super_user); - my $bug = Bugzilla::Bug->new({ id => $bug_id, cache => 1 }); - Bugzilla->logout; - - # create a bug if there are any mozreview attachments - my @reviews = grep { $_->contenttype eq RB_CONTENT_TYPE } @{ $bug->attachments }; - if (@reviews) { - - # build comment - my $comment = $target eq 'bug' - ? "Bug $bug_id has MozReview reviews and is no longer public." - : "MozReview attachment $attach_id on Bug $bug_id is no longer public."; - $comment .= "\n\n"; - foreach my $attachment (@reviews) { - $comment .= $attachment->data . "\n"; - } - - # create bug - my $user = Bugzilla::User->new({ name => AUTOMATION_USER, cache => 1 }); - die "Invalid User: " . AUTOMATION_USER . "\n" unless $user; - Bugzilla->set_user($user); - my $new_bug = Bugzilla::Bug->create({ - short_desc => "[SECURITY] Bug $bug_id is no longer public", - product => $config->{product}, - component => $config->{component}, - bug_severity => 'normal', - groups => [ map { trim($_) } split(',', $config->{group}) ], - op_sys => 'Unspecified', - rep_platform => 'Unspecified', - version => $config->{version}, - cc => [ map { trim($_) } split(',', $config->{cc}) ], - comment => $comment, - }); - Bugzilla::BugMail::Send($new_bug->id, { changer => Bugzilla->user }); - Bugzilla->logout; - - $logger->info("Created bug " . $new_bug->id); - } - }; - my $error = $@; - Bugzilla->logout; - if ($error) { - return (PUSH_RESULT_TRANSIENT, clean_error($error)); - } - - return PUSH_RESULT_OK; -} - -1; diff --git a/extensions/Push/t/ReviewBoard.t b/extensions/Push/t/ReviewBoard.t deleted file mode 100644 index c752e34ef..000000000 --- a/extensions/Push/t/ReviewBoard.t +++ /dev/null @@ -1,225 +0,0 @@ -#!/usr/bin/perl -T -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. -use strict; -use warnings; -use lib qw( . lib local/lib/perl5 ); - -use Test::More; -use Bugzilla; -use Bugzilla::Extension; -use Bugzilla::Attachment; -use Scalar::Util 'blessed'; - -BEGIN { - eval { - require Test::LWP::UserAgent; - require Test::MockObject; - }; - if ($@) { - plan skip_all => - 'Tests require Test::LWP::UserAgent and Test::MockObject'; - exit; - } -} - -BEGIN { - Bugzilla->extensions; # load all of them - use_ok 'Bugzilla::Extension::Push::Connector::ReviewBoard::Client'; - use_ok 'Bugzilla::Extension::Push::Constants'; -} - -my ($push) = grep { blessed($_) eq 'Bugzilla::Extension::Push' } @{Bugzilla->extensions }; -my $connectors = $push->_get_instance->connectors; -my $con = $connectors->by_name('ReviewBoard'); - -my $ua_204 = Test::LWP::UserAgent->new; -$ua_204->map_response( - qr{https://reviewboard-dev\.allizom\.org/api/review-requests/\d+}, - HTTP::Response->new('204')); - -my $ua_404 = Test::LWP::UserAgent->new; -$ua_404->map_response( - qr{https://reviewboard-dev\.allizom\.org/api/review-requests/\d+}, - HTTP::Response->new('404', undef, undef, q[{ "err": { "code": 100, "msg": "Object does not exist" }, "stat": "fail" }])); - -# forbidden -my $ua_403 = Test::LWP::UserAgent->new; -$ua_403->map_response( - qr{https://reviewboard-dev\.allizom\.org/api/review-requests/\d+}, - HTTP::Response->new('403', undef, undef, q[ {"err":{"code":101,"msg":"You don't have permission for this"},"stat":"fail"}])); - -# not logged in -my $ua_401 = Test::LWP::UserAgent->new; -$ua_401->map_response( - qr{https://reviewboard-dev\.allizom\.org/api/review-requests/\d+}, - HTTP::Response->new('401', undef, undef, q[ { "err": { "code": 103, "msg": "You are not logged in" }, "stat": "fail" } ])); - -# not logged in -my $ua_500 = Test::LWP::UserAgent->new; -$ua_500->map_response( - qr{https://reviewboard-dev\.allizom\.org/api/review-requests/\d+}, - HTTP::Response->new('500')); - -$con->client->{useragent} = $ua_204; -$con->config->{base_uri} = 'https://reviewboard-dev.allizom.org'; -$con->client->{base_uri} = 'https://reviewboard-dev.allizom.org'; - -{ - my $msg = message( - event => { - routing_key => 'attachment.modify:is_private', - target => 'attachment', - }, - attachment => { - is_private => 1, - content_type => 'text/plain', - bug => { id => 1, is_private => 0 }, - }, - ); - - ok(not($con->should_send($msg)), "text/plain message should not be sent"); -} - -my $data = slurp("extensions/Push/t/rblink.txt"); -Bugzilla::User::DEFAULT_USER->{userid} = 42; -Bugzilla->set_user(Bugzilla::User->super_user); -diag " " . Bugzilla::User->super_user->id; - -my $dbh = Bugzilla->dbh; -$dbh->bz_start_transaction; -my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); -my $bug = Bugzilla::Bug->new({id => 9000}); -my $attachment = Bugzilla::Attachment->create({ - bug => $bug, - creation_ts => $timestamp, - data => $data, - attach_size => length($data), - description => "rblink.txt", - filename => "rblink.txt", - isprivate => 1, - ispatch => 0, - mimetype => 'text/x-review-board-request' -}); -diag "".$attachment->id; -$dbh->bz_commit_transaction; - -{ - my $msg = message( - event => { - routing_key => 'attachment.modify:cc,is_private', - target => 'attachment', - }, - attachment => { - id => $attachment->id, - is_private => 1, - content_type => 'text/x-review-board-request', - bug => { id => $bug->id, is_private => 0 }, - }, - ); - ok($con->should_send($msg), "rb attachment should be sent"); - - { - my ($rv, $err) = $con->send($msg); - is($rv, PUSH_RESULT_OK, "good push result"); - diag $err if $err; - } - - { - local $con->client->{useragent} = $ua_404; - my ($rv, $err) = $con->send($msg); - is($rv, PUSH_RESULT_OK, "good push result for 404"); - diag $err if $err; - } - - - { - local $con->client->{useragent} = $ua_403; - my ($rv, $err) = $con->send($msg); - is($rv, PUSH_RESULT_TRANSIENT, "transient error on 403"); - diag $err if $err; - } - - - { - local $con->client->{useragent} = $ua_401; - my ($rv, $err) = $con->send($msg); - is($rv, PUSH_RESULT_TRANSIENT, "transient error on 401"); - diag $err if $err; - } - - { - local $con->client->{useragent} = $ua_500; - my ($rv, $err) = $con->send($msg); - is($rv, PUSH_RESULT_TRANSIENT, "transient error on 500"); - diag $err if $err; - } -} - -{ - my $msg = message( - event => { - routing_key => 'bug.modify:is_private', - target => 'bug', - }, - bug => { - is_private => 1, - id => $bug->id, - }, - ); - - ok($con->should_send($msg), "rb attachment should be sent"); - my ($rv, $err) = $con->send($msg); - is($rv, PUSH_RESULT_OK, "good push result"); - - { - local $con->client->{useragent} = $ua_404; - my ($rv, $err) = $con->send($msg); - is($rv, PUSH_RESULT_OK, "good push result for 404"); - } - - { - local $con->client->{useragent} = $ua_403; - my ($rv, $err) = $con->send($msg); - is($rv, PUSH_RESULT_TRANSIENT, "transient error on 404"); - diag $err if $err; - } - - - { - local $con->client->{useragent} = $ua_401; - my ($rv, $err) = $con->send($msg); - is($rv, PUSH_RESULT_TRANSIENT, "transient error on 401"); - diag $err if $err; - } - - { - local $con->client->{useragent} = $ua_401; - my ($rv, $err) = $con->send($msg); - is($rv, PUSH_RESULT_TRANSIENT, "transient error on 401"); - diag $err if $err; - } -} - -sub message { - my $msg_data = { @_ }; - - return Test::MockObject->new - ->set_always( routing_key => $msg_data->{event}{routing_key} ) - ->set_always( payload_decoded => $msg_data ); -} - -sub slurp { - my $file = shift; - local $/ = undef; - open my $fh, '<', $file or die "unable to open $file"; - my $s = readline $fh; - close $fh; - return $s; -} - -done_testing; diff --git a/extensions/REMO/template/en/default/bug/create/comment-remo-budget.txt.tmpl b/extensions/REMO/template/en/default/bug/create/comment-remo-budget.txt.tmpl index c5f18ef76..0531aeb2f 100644 --- a/extensions/REMO/template/en/default/bug/create/comment-remo-budget.txt.tmpl +++ b/extensions/REMO/template/en/default/bug/create/comment-remo-budget.txt.tmpl @@ -24,13 +24,13 @@ # enter_bug.cgi) can be access via Bugzilla.cgi.param. It can be used to # pull out various custom fields and format an initial Description entry # from them. - #%] + #%] [% USE Bugzilla %] [% cgi = Bugzilla.cgi %] Requester info: -Requester: [% cgi.param('firstname') %] [%+ cgi.param('lastname') %] +Requester: [% cgi.param('firstname') %] [%+ cgi.param('lastname') %] Profile page: [% cgi.param('profilepage') %] Event page: [% cgi.param('eventpage') %] Funtional Goals: @@ -45,7 +45,7 @@ Paypal Account: [% cgi.param('paypal') %] Country You Reside: [% cgi.param('country') %] Advance payment needed: [% IF cgi.param('advancepayment') %]Yes[% ELSE %]No[% END %] -Budget breakdown: +Budget breakdown: Total amount requested in $USD: [% cgi.param('budgettotal') %] Costs per service: diff --git a/extensions/REMO/template/en/default/bug/create/comment-remo-swag.txt.tmpl b/extensions/REMO/template/en/default/bug/create/comment-remo-swag.txt.tmpl index 2d4bb6215..c4187558d 100644 --- a/extensions/REMO/template/en/default/bug/create/comment-remo-swag.txt.tmpl +++ b/extensions/REMO/template/en/default/bug/create/comment-remo-swag.txt.tmpl @@ -25,11 +25,11 @@ # enter_bug.cgi) can be access via Bugzilla.cgi.param. It can be used to # pull out various custom fields and format an initial Description entry # from them. - #%] + #%] [% USE Bugzilla %] [% cgi = Bugzilla.cgi %] -Requester info: +Requester info: First name: [% cgi.param('firstname') %] Last name: [% cgi.param('lastname') %] @@ -54,9 +54,9 @@ Phone: [% cgi.param("shiptophone") %] [%+ IF cgi.param("shiptoidrut") %]Custom reference: [% cgi.param("shiptoidrut") %][% END %] Addition information for delivery person: -[%+ cgi.param('shipadditional') %] +[%+ cgi.param('shipadditional') %] -Swag requested: +Swag requested: Stickers: [% IF cgi.param('stickers') %]Yes[% ELSE %]No[% END %] Buttons: [% IF cgi.param('buttons') %]Yes[% ELSE %]No[% END %] 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 index e13fba024..329670bdf 100644 --- 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 @@ -24,7 +24,7 @@ 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" %] +[% 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 %]'. diff --git a/extensions/REMO/template/en/default/pages/comment-remo-form-payment.txt.tmpl b/extensions/REMO/template/en/default/pages/comment-remo-form-payment.txt.tmpl index 95c0af6e8..b9a5f02d1 100644 --- a/extensions/REMO/template/en/default/pages/comment-remo-form-payment.txt.tmpl +++ b/extensions/REMO/template/en/default/pages/comment-remo-form-payment.txt.tmpl @@ -26,9 +26,9 @@ Mozilla Reps Payment Request Requester info: -First name: [% cgi.param('firstname') %] -Last name: [% cgi.param('lastname') %] -Wiki user profile: [% cgi.param('wikiprofile') %] +First name: [% cgi.param('firstname') %] +Last name: [% cgi.param('lastname') %] +Wiki user profile: [% cgi.param('wikiprofile') %] Event wiki page: [% cgi.param('wikipage') %] Budget request [% terms.bug %]: [% cgi.param('bug_id') %] Have you already received payment for this event? [% IF cgi.param('receivedpayment') %]Yes[% ELSE %]No[% END %] diff --git a/extensions/REMO/template/en/default/pages/remo-form-payment.html.tmpl b/extensions/REMO/template/en/default/pages/remo-form-payment.html.tmpl index 1e1889089..0f594e9ae 100644 --- a/extensions/REMO/template/en/default/pages/remo-form-payment.html.tmpl +++ b/extensions/REMO/template/en/default/pages/remo-form-payment.html.tmpl @@ -92,7 +92,7 @@ <br> Payment information:<br> Bank name:<br> - Bank address: <br> + Bank address: <br> IBAN:<br> Swift code/BIC:<br> Additional bank details (if necessary): diff --git a/extensions/REMO/web/js/form_validate.js b/extensions/REMO/web/js/form_validate.js index 6c8fa6f07..3e1ae60f6 100644 --- a/extensions/REMO/web/js/form_validate.js +++ b/extensions/REMO/web/js/form_validate.js @@ -1,7 +1,7 @@ /** * Some Form Validation and Interaction **/ -//Makes sure that there is an '@' in the address with a '.' +//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) { diff --git a/extensions/REMO/web/js/swag.js b/extensions/REMO/web/js/swag.js index 3b69bbab8..1c7281108 100644 --- a/extensions/REMO/web/js/swag.js +++ b/extensions/REMO/web/js/swag.js @@ -24,37 +24,37 @@ function getTotal(item_array) { return total; } -function calculateTotalSwag() { - document.getElementById('Totalswag').value = +function calculateTotalSwag() { + document.getElementById('Totalswag').value = getTotal( new Array('Lanyards', 'Stickers', 'Bracelets', 'Tattoos', 'Buttons', 'Posters')); - + } -function calculateTotalMensShirts() { - document.getElementById('mens_total').value = +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 = +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/SecureMail/template/en/default/account/email/encryption-required.txt.tmpl b/extensions/SecureMail/template/en/default/account/email/encryption-required.txt.tmpl index 55b716864..872cea30c 100644 --- a/extensions/SecureMail/template/en/default/account/email/encryption-required.txt.tmpl +++ b/extensions/SecureMail/template/en/default/account/email/encryption-required.txt.tmpl @@ -12,7 +12,7 @@ preferences. [% IF bug_id || email_type == 'whine' %] In order to receive the full text of similar mails in the future, please -go to: +go to: [%+ urlbase %]userprefs.cgi?tab=securemail and provide a key or certificate. 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 db595a23f..ffe182de8 100644 --- a/extensions/SecureMail/template/en/default/account/prefs/securemail.html.tmpl +++ b/extensions/SecureMail/template/en/default/account/prefs/securemail.html.tmpl @@ -11,7 +11,7 @@ # The Original Code is the Bugzilla Bug Tracking System. # # The Initial Developer of the Original Code is the Mozilla Corporation. - # Portions created by the Initial Developer are Copyright (C) 2008 the + # Portions created by the Initial Developer are Copyright (C) 2008 the # Initial Developer. All Rights Reserved. # # Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> @@ -23,9 +23,9 @@ </div> [% END %] -<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 %] -will only be sent encrypted. Enter your PGP/GPG public key or +<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 %] +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> <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> diff --git a/extensions/SecureMail/template/en/default/hook/account/prefs/prefs-tabs.html.tmpl b/extensions/SecureMail/template/en/default/hook/account/prefs/prefs-tabs.html.tmpl index 70a40e592..1662e28af 100644 --- a/extensions/SecureMail/template/en/default/hook/account/prefs/prefs-tabs.html.tmpl +++ b/extensions/SecureMail/template/en/default/hook/account/prefs/prefs-tabs.html.tmpl @@ -17,7 +17,7 @@ # All Rights Reserved. # # Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> - # Gervase Markham <gerv@gerv.net> + # Gervase Markham <gerv@gerv.net> #%] [% tabs = tabs.import([{ diff --git a/extensions/SecureMail/template/en/default/hook/admin/groups/create-field.html.tmpl b/extensions/SecureMail/template/en/default/hook/admin/groups/create-field.html.tmpl index 27c644d02..a3d5069cc 100644 --- a/extensions/SecureMail/template/en/default/hook/admin/groups/create-field.html.tmpl +++ b/extensions/SecureMail/template/en/default/hook/admin/groups/create-field.html.tmpl @@ -11,7 +11,7 @@ # The Original Code is the Bugzilla Bug Tracking System. # # The Initial Developer of the Original Code is the Mozilla Corporation. - # Portions created by the Initial Developer are Copyright (C) 2008 the + # Portions created by the Initial Developer are Copyright (C) 2008 the # Initial Developer. All Rights Reserved. # # Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> @@ -21,5 +21,5 @@ <td colspan="3"> <input type="checkbox" id="secure_mail" name="secure_mail" [% ' checked="checked"' IF group.secure_mail %]> - </td> -</tr> + </td> +</tr> diff --git a/extensions/SecureMail/template/en/default/hook/admin/groups/edit-field.html.tmpl b/extensions/SecureMail/template/en/default/hook/admin/groups/edit-field.html.tmpl index 253fed29e..7aaf35d7d 100644 --- a/extensions/SecureMail/template/en/default/hook/admin/groups/edit-field.html.tmpl +++ b/extensions/SecureMail/template/en/default/hook/admin/groups/edit-field.html.tmpl @@ -11,7 +11,7 @@ # The Original Code is the Bugzilla Bug Tracking System. # # The Initial Developer of the Original Code is the Mozilla Corporation. - # Portions created by the Initial Developer are Copyright (C) 2008 the + # Portions created by the Initial Developer are Copyright (C) 2008 the # Initial Developer. All Rights Reserved. # # Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> diff --git a/extensions/SecureMail/template/en/default/hook/admin/users/userdata-end.html.tmpl b/extensions/SecureMail/template/en/default/hook/admin/users/userdata-end.html.tmpl index e5e299ef9..cf0ec3e03 100644 --- a/extensions/SecureMail/template/en/default/hook/admin/users/userdata-end.html.tmpl +++ b/extensions/SecureMail/template/en/default/hook/admin/users/userdata-end.html.tmpl @@ -14,7 +14,7 @@ [% otheruser.public_key ? "Yes" : "No" %] </td> </tr> - + <tr> <th>Member of Secure Mail Group:</th> <td> diff --git a/extensions/SecureMail/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/SecureMail/template/en/default/hook/global/user-error-errors.html.tmpl index 46b093674..507874fe4 100644 --- a/extensions/SecureMail/template/en/default/hook/global/user-error-errors.html.tmpl +++ b/extensions/SecureMail/template/en/default/hook/global/user-error-errors.html.tmpl @@ -11,7 +11,7 @@ # The Original Code is the Bugzilla Bug Tracking System. # # The Initial Developer of the Original Code is the Mozilla Corporation. - # Portions created by the Initial Developer are Copyright (C) 2008 the + # Portions created by the Initial Developer are Copyright (C) 2008 the # Initial Developer. All Rights Reserved. # # Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> @@ -20,8 +20,8 @@ [% IF error == "securemail_invalid_key" %] [% title = "Invalid Public Key" %] We were unable to read the public key that you entered. Make sure - that you are entering either an ASCII-armored PGP/GPG public key, - including the "BEGIN PGP PUBLIC KEY BLOCK" and "END PGP PUBLIC KEY BLOCK" + that you are entering either an ASCII-armored PGP/GPG public key, + including the "BEGIN PGP PUBLIC KEY BLOCK" and "END PGP PUBLIC KEY BLOCK" lines, or a PEM format (Base64-encoded X.509) S/MIME key, including the BEGIN CERTIFICATE and END CERTIFICATE lines.<br><br>[% errstr FILTER html %] [% END %] 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 928c7f1d4..378d007f0 100644 --- a/extensions/SecureMail/template/en/default/pages/securemail/help.html.tmpl +++ b/extensions/SecureMail/template/en/default/pages/securemail/help.html.tmpl @@ -24,8 +24,8 @@ 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 +[% 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 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"> @@ -36,9 +36,9 @@ be required to decrypt it to view the reset instructions. <b>S/MIME Keys must be in PEM format - i.e. Base64-encoded text, with the first line containing BEGIN CERTIFICATE.</b></p> -<p>S/MIME certificates can be obtained from a number of providers. -Once you have it, export it from your browser as a .p12 file and import it into your mail client. -You'll need to provide a password when you export - pick a strong one, +<p>S/MIME certificates can be obtained from a number of providers. +Once you have it, export it from your browser as a .p12 file and import it into your mail client. +You'll need to provide a password when you export - pick a strong one, and then back up the .p12 file somewhere safe.</p> <p>Import on Thunderbird as follows:</p> @@ -81,7 +81,7 @@ Then, you need to convert it to a .pem file. Here are two possible ways to do th <p> Open the .pem file in a text editor. You can recognise the public key because -it starts "BEGIN CERTIFICATE" and ends "END CERTIFICATE" and +it starts "BEGIN CERTIFICATE" and ends "END CERTIFICATE" and has an appropriate friendly name (e.g. "StartCom Free Certificate Member's StartCom Ltd. ID").</p> <p>Paste the contents of the .pem file into the SecureMail text field in [% terms.Bugzilla %].</p> @@ -117,7 +117,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 [% terms.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/template/en/default/hook/global/messages-messages.html.tmpl b/extensions/SiteMapIndex/template/en/default/hook/global/messages-messages.html.tmpl index 0d0e9fd74..1e2b1788b 100644 --- a/extensions/SiteMapIndex/template/en/default/hook/global/messages-messages.html.tmpl +++ b/extensions/SiteMapIndex/template/en/default/hook/global/messages-messages.html.tmpl @@ -30,7 +30,7 @@ [% ELSIF message_tag == "sitemap_no_urlbase" %] You have not yet set the "urlbase" parameter. We cannot update - search engines and inform them about your sitemap without a + search engines and inform them about your sitemap without a urlbase. Please set the "urlbase" parameter and re-run checksetup.pl. diff --git a/extensions/Splinter/web/splinter.js b/extensions/Splinter/web/splinter.js index 277a7ff86..8fde9998a 100644 --- a/extensions/Splinter/web/splinter.js +++ b/extensions/Splinter/web/splinter.js @@ -116,7 +116,7 @@ Splinter.Bug = { } } else { tzoffset = parseInt(m[8], 10); - } + } var unadjustedDate = new Date(Date.UTC(m[1], m[2] - 1, m[3], m[4], m[5])); @@ -129,7 +129,7 @@ Splinter.Bug = { return new Date(unadjustedDate.getTime() - sign * adjustmentHours * 3600000 - sign * adjustmentMinutes * 60000); - }, + }, _formatWho : function(name, email) { if (name && email) { @@ -207,14 +207,14 @@ Splinter.Dialog.prototype = { draggable: false, close: false, hideaftersubmit: true, - constraintoviewport: true + constraintoviewport: true }); this.dialog.setHeader(prompt); }, addButton : function (label, callback, isdefault) { - this.buttons.push({ text : label, - handler : function () { this.hide(); callback(); }, + this.buttons.push({ text : label, + handler : function () { this.hide(); callback(); }, isDefault : isdefault }); this.dialog.cfg.queueProperty("buttons", this.buttons); }, @@ -325,13 +325,13 @@ Splinter.Patch.Hunk.prototype = { lines[j][2] |= Splinter.Patch.CHANGED; } } - + currentStart = -1; currentOldCount = 0; currentNewCount = 0; } } - + var i; for (i = 0; i < rawlines.length; i++) { var line = rawlines[i]; @@ -363,7 +363,7 @@ Splinter.Patch.Hunk.prototype = { } currentNewCount++; } - } + } // git mail-formatted patches end with --\n<git version> like a signature // This is troublesome since it looks like a subtraction at the end @@ -398,7 +398,7 @@ Splinter.Patch.Hunk.prototype = { if (line[1] != null) { newLine++; } - } + } } }; @@ -436,22 +436,22 @@ Splinter.Patch.File.prototype = { } if ((oldLine != null && oldLine < hunk.oldStart + hunk.oldCount) || - (newLine != null && newLine < hunk.newStart + hunk.newCount)) + (newLine != null && newLine < hunk.newStart + hunk.newCount)) { var location = -1; hunk.iterate(function(loc, oldl, oldText, newl, newText, flags) { if ((oldLine == null || oldl == oldLine) && - (newLine == null || newl == newLine)) + (newLine == null || newl == newLine)) { location = loc; } }); - + if (location != -1) { return location; } } - } + } throw "Bad oldLine,newLine: " + oldLine + "," + newLine; }, @@ -645,7 +645,7 @@ Splinter.Patch.Patch.prototype = { } else { status = Splinter.Patch.CHANGED; } - } + } this.files.push(new Splinter.Patch.File(filename, status, extra, hunks)); @@ -785,7 +785,7 @@ Splinter.Review.File.prototype = { var i; for (i = 0; i < this.comments.length; i++) { if (this.comments[i].location == location && - this.comments[i].type == type) + this.comments[i].type == type) { return this.comments[i]; } @@ -857,19 +857,19 @@ Splinter.Review.File.prototype = { addNewLine(newLine); unchangedLines++; } else { - if ((comment.type == Splinter.Patch.REMOVED - || comment.type == Splinter.Patch.CHANGED) - && oldText != null) + if ((comment.type == Splinter.Patch.REMOVED + || comment.type == Splinter.Patch.CHANGED) + && oldText != null) { - patchLines.push('> -' + oldText + + patchLines.push('> -' + oldText + Splinter.Review._noNewLine(flags, Splinter.Patch.OLD_NONEWLINE)); addOldLine(oldLine); } - if ((comment.type == Splinter.Patch.ADDED - || comment.type == Splinter.Patch.CHANGED) - && newText != null) + if ((comment.type == Splinter.Patch.ADDED + || comment.type == Splinter.Patch.CHANGED) + && newText != null) { - patchLines.push('> +' + newText + + patchLines.push('> +' + newText + Splinter.Review._noNewLine(flags, Splinter.Patch.NEW_NONEWLINE)); addNewLine(newLine); } @@ -1092,7 +1092,7 @@ Splinter.Review.Review.prototype = { } if ((oldStart == null || oldLine == oldStart + oldCount) && - (newStart == null || newLine == newStart + newCount)) + (newStart == null || newLine == newStart + newCount)) { commentText = rawlines.slice(i + 1).join("\n"); break; @@ -1175,7 +1175,7 @@ Splinter.Review.Review.prototype = { str += file.toString(); } } - + return str; } }; @@ -1276,8 +1276,8 @@ Splinter.ReviewStorage.LocalReviewStorage.prototype = { saveDraft : function(bug, attachment, review, extraProps) { var propertyName = this._reviewPropertyName(bug, attachment); - if (!extraProps) { - extraProps = {}; + if (!extraProps) { + extraProps = {}; } extraProps.isDraft = true; this._updateOrCreateReviewInfo(bug, attachment, extraProps); @@ -1307,7 +1307,7 @@ Splinter.UPDATE_ATTACHMENT_SUCCESS = /<title>\s*Changes\s+Submitted/; Splinter.LINE_RE = /(?!$)([^\r\n]*)(?:\r\n|\r|\n|$)/g; Splinter.displayError = function (msg) { - var el = new Element(document.createElement('p')); + var el = new Element(document.createElement('p')); el.appendChild(document.createTextNode(msg)); Dom.get('error').appendChild(Dom.get(el)); Dom.setStyle('error', 'display', 'block'); @@ -1318,7 +1318,7 @@ Splinter.publishReview = function () { Splinter.theReview.setIntro(Dom.get('myComment').value); if (Splinter.reviewStorage) { - Splinter.reviewStorage.draftPublished(Splinter.theBug, + Splinter.reviewStorage.draftPublished(Splinter.theBug, Splinter.theAttachment); } @@ -1346,13 +1346,13 @@ Splinter.publishReview = function () { // This is a "magic string" used to identify review comments if (Splinter.theReview.toString()) { var comment = "Review of attachment " + Splinter.theAttachment.id + ":\n" + - "-----------------------------------------------------------------\n\n" + + "-----------------------------------------------------------------\n\n" + Splinter.theReview.toString(); publish_review.value = comment; } - if (Splinter.theAttachment.status - && Dom.get('attachmentStatus').value != Splinter.theAttachment.status) + if (Splinter.theAttachment.status + && Dom.get('attachmentStatus').value != Splinter.theAttachment.status) { publish_attach_status.value = Dom.get('attachmentStatus').value; } @@ -1367,7 +1367,7 @@ Splinter.doDiscardReview = function () { Dom.get('myComment').value = ''; Dom.setStyle('emptyCommentNotice', 'display', 'block'); - + var i; for (i = 0; i < Splinter.theReview.files.length; i++) { while (Splinter.theReview.files[i].comments.length > 0) { @@ -1481,7 +1481,7 @@ Splinter.saveDraft = function () { filesReviewed[file.filename] = true; } } - Splinter.reviewStorage.saveDraft(Splinter.theBug, Splinter.theAttachment, Splinter.theReview, + Splinter.reviewStorage.saveDraft(Splinter.theBug, Splinter.theAttachment, Splinter.theReview, { 'filesReviewed' : filesReviewed }); draftSaved = true; } else { @@ -1614,7 +1614,7 @@ Splinter.addCommentDisplay = function (commentArea, comment) { Dom.addClass(reviewer, 'reviewer'); reviewer.appendChild(document.createTextNode(review.who)); reviewer.appendTo(reviewInfo); - + var reviewDate = new Element(document.createElement('div')); Dom.addClass(reviewDate, 'review-date'); reviewDate.appendChild(document.createTextNode(Splinter.Utils.formatDate(review.date))); @@ -1693,7 +1693,7 @@ Splinter.insertCommentEditor = function (commentArea, file, location, type) { var separatorClass = Splinter.getSeparatorClass(type); var nodes = Dom.getElementsByClassName('reviewer-0', 'div', commentArea); - var i; + var i; for (i = 0; i < nodes.length; i++) { if (separatorClass && Dom.hasClass(nodes[i], separatorClass)) { nodes[i].parentNode.removeChild(nodes[i]); @@ -1714,7 +1714,7 @@ Splinter.insertCommentEditor = function (commentArea, file, location, type) { Dom.setAttribute(commentEditor, 'id', 'commentEditor'); Dom.addClass(commentEditor, typeClass); commentEditor.appendTo(commentArea); - + var commentEditorInner = new Element(document.createElement('div')); Dom.setAttribute(commentEditorInner, 'id', 'commentEditorInner'); commentEditorInner.appendTo(commentEditor); @@ -1728,7 +1728,7 @@ Splinter.insertCommentEditor = function (commentArea, file, location, type) { Dom.setAttribute(commentTextArea, 'tabindex', 1); commentTextArea.appendChild(document.createTextNode(previousText)); commentTextArea.appendTo(commentTextFrame); - Event.addListener('commentTextArea', 'keydown', function (e) { + Event.addListener('commentTextArea', 'keydown', function (e) { if (e.which == 13 && e.ctrlKey) { Splinter.saveComment(); } else if (e.which == 27) { @@ -2213,7 +2213,7 @@ Splinter.addNavigationLink = function (identifier, title, callback, selected) { var navigationDiv = Dom.get('navigation'); if (Dom.getChildren(navigationDiv).length > 0) { navigationDiv.appendChild(document.createTextNode(' | ')); - } + } var navigationLink = new Element(document.createElement('a')); Dom.addClass(navigationLink, 'navigation-link'); @@ -2224,13 +2224,13 @@ Splinter.addNavigationLink = function (identifier, title, callback, selected) { navigationLink.appendTo(navigationDiv); // FIXME: Find out why I need to use an id here instead of just passing - // navigationLink to Event.addListener() + // navigationLink to Event.addListener() Event.addListener('switch-' + encodeURIComponent(identifier), 'click', function () { if (!Dom.hasClass(this, 'navigation-link-selected')) { callback(); } }); - + if (selected) { Dom.addClass(navigationLink, 'navigation-link-selected'); } @@ -2241,7 +2241,7 @@ Splinter.addNavigationLink = function (identifier, title, callback, selected) { Splinter.showOverview = function () { Splinter.selectNavigationLink('__OVERVIEW__'); Dom.setStyle('overview', 'display', 'block'); - Dom.getElementsByClassName('file', 'div', '', function (node) { + Dom.getElementsByClassName('file', 'div', '', function (node) { Dom.setStyle(node, 'display', 'none'); }); if (!Splinter.readOnly) @@ -2358,7 +2358,7 @@ Splinter.start = function () { Dom.setAttribute(haveDraftNotice, 'id', 'haveDraftNotice'); haveDraftNotice.appendChild(document.createTextNode('Draft')); haveDraftNotice.appendTo(navigation); - + var clear = new Element(document.createElement('div')); Dom.addClass(clear, 'clear'); clear.appendTo(navigation); @@ -2409,7 +2409,7 @@ Splinter.start = function () { reviewIntro.appendTo(reviewerBox); Dom.setStyle('oldReviews', 'display', 'block'); - + Splinter.appendReviewComments(review, reviewerBox); } } @@ -2424,7 +2424,7 @@ Splinter.start = function () { Dom.setStyle('restored', 'display', 'block'); for (i = 0; i < storedReviews.length; i++) { if (storedReviews[i].bugId == Splinter.theBug.id && - storedReviews[i].attachmentId == Splinter.theAttachment.id) + storedReviews[i].attachmentId == Splinter.theAttachment.id) { Splinter.replaceText(Dom.get("restoredLastModified"), Splinter.Utils.formatDate(new Date(storedReviews[i].modificationTime))); // Restore file reviewed checkboxes @@ -2625,7 +2625,7 @@ Splinter.showChooseAttachment = function () { responseType: YAHOO.util.DataSource.TYPE_JSARRAY, responseSchema: { fields:["id","description","date", "extra"] } }; - + var columnDefs = [ { key: "id", label: "ID", formatter: attachLink }, { key: "description", label: "Description", formatter: attachDesc }, @@ -2635,7 +2635,7 @@ Splinter.showChooseAttachment = function () { var dataSource = new YAHOO.util.LocalDataSource(attachData, dsConfig); var dataTable = new YAHOO.widget.DataTable("chooseAttachmentTable", columnDefs, dataSource); - + Dom.setStyle('chooseAttachment', 'display', 'block'); }; @@ -2651,7 +2651,7 @@ Splinter.quickHelpToggle = function () { quickHelpContent.style.display = 'none'; quickHelpShow.style.display = 'block'; } -}; +}; Splinter.init = function () { Splinter.showNote(); @@ -2674,7 +2674,7 @@ Splinter.init = function () { if (Splinter.attachmentId) { Splinter.theAttachment = Splinter.theBug.getAttachment(Splinter.attachmentId); - + if (Splinter.theAttachment == null) { Splinter.displayError("Attachment " + Splinter.attachmentId + " is not an attachment to bug " + Splinter.theBug.id); } @@ -2704,8 +2704,8 @@ Splinter.init = function () { Dom.setStyle('attachInfo', 'display', 'block'); Dom.setStyle('quickHelpShow', 'display', 'block'); - - document.title = "Patch Review of Attachment " + Splinter.theAttachment.id + + + document.title = "Patch Review of Attachment " + Splinter.theAttachment.id + " for Bug " + Splinter.theBug.id; Splinter.thePatch = new Splinter.Patch.Patch(Splinter.theAttachment.data); @@ -2715,4 +2715,4 @@ Splinter.init = function () { } }; -YAHOO.util.Event.addListener(window, 'load', Splinter.init); +YAHOO.util.Event.addListener(window, 'load', Splinter.init); diff --git a/extensions/Voting/template/en/default/hook/account/prefs/email-relationships.html.tmpl b/extensions/Voting/template/en/default/hook/account/prefs/email-relationships.html.tmpl index 0bd81eae1..4c2609609 100644 --- a/extensions/Voting/template/en/default/hook/account/prefs/email-relationships.html.tmpl +++ b/extensions/Voting/template/en/default/hook/account/prefs/email-relationships.html.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/hook/admin/products/edit-common-rows.html.tmpl b/extensions/Voting/template/en/default/hook/admin/products/edit-common-rows.html.tmpl index fde6434de..8fa43734b 100644 --- a/extensions/Voting/template/en/default/hook/admin/products/edit-common-rows.html.tmpl +++ b/extensions/Voting/template/en/default/hook/admin/products/edit-common-rows.html.tmpl @@ -14,16 +14,16 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] -[% DEFAULT +[% DEFAULT product.maxvotesperbug = constants.DEFAULT_VOTES_PER_BUG product.votesperuser = 0 product.votestoconfirm = 0 %] - + <tr> <th align="right">Maximum votes per person:</th> <td><input size="5" maxlength="5" name="votesperuser" id="votesperuser" 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..01005d776 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 @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl b/extensions/Voting/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl index bbf0350a1..ad475a76b 100644 --- a/extensions/Voting/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl +++ b/extensions/Voting/template/en/default/hook/admin/sanitycheck/messages-statuses.html.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/hook/admin/users/confirm-delete-warn_safe.html.tmpl b/extensions/Voting/template/en/default/hook/admin/users/confirm-delete-warn_safe.html.tmpl index a753e3a66..5a9d315c2 100644 --- a/extensions/Voting/template/en/default/hook/admin/users/confirm-delete-warn_safe.html.tmpl +++ b/extensions/Voting/template/en/default/hook/admin/users/confirm-delete-warn_safe.html.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] 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 b57a5cb27..e502c1e3a 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 @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] [% IF bug.product_obj.votesperuser %] @@ -23,7 +23,7 @@ with <a href="page.cgi?id=voting/bug.html&bug_id= [%- bug.id FILTER uri %]"> - [%- bug.votes FILTER html %] + [%- bug.votes FILTER html %] [% IF bug.votes == 1 %] vote [% ELSE %] diff --git a/extensions/Voting/template/en/default/hook/bug/format_comment-type.txt.tmpl b/extensions/Voting/template/en/default/hook/bug/format_comment-type.txt.tmpl index ebba6fcab..59c8eeedc 100644 --- a/extensions/Voting/template/en/default/hook/bug/format_comment-type.txt.tmpl +++ b/extensions/Voting/template/en/default/hook/bug/format_comment-type.txt.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/hook/bug/process/header-title.html.tmpl b/extensions/Voting/template/en/default/hook/bug/process/header-title.html.tmpl index a4530653b..b4dd16e90 100644 --- a/extensions/Voting/template/en/default/hook/bug/process/header-title.html.tmpl +++ b/extensions/Voting/template/en/default/hook/bug/process/header-title.html.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/hook/bug/process/results-title.html.tmpl b/extensions/Voting/template/en/default/hook/bug/process/results-title.html.tmpl index ae0d465dc..fd8a4cadd 100644 --- a/extensions/Voting/template/en/default/hook/bug/process/results-title.html.tmpl +++ b/extensions/Voting/template/en/default/hook/bug/process/results-title.html.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/hook/bug/show-header-end.html.tmpl b/extensions/Voting/template/en/default/hook/bug/show-header-end.html.tmpl index 2e2c2d995..55d3bf468 100644 --- a/extensions/Voting/template/en/default/hook/bug/show-header-end.html.tmpl +++ b/extensions/Voting/template/en/default/hook/bug/show-header-end.html.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/hook/global/code-error-errors.html.tmpl b/extensions/Voting/template/en/default/hook/global/code-error-errors.html.tmpl index 50e915941..7763f15d8 100644 --- a/extensions/Voting/template/en/default/hook/global/code-error-errors.html.tmpl +++ b/extensions/Voting/template/en/default/hook/global/code-error-errors.html.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/hook/global/field-descs-end.none.tmpl b/extensions/Voting/template/en/default/hook/global/field-descs-end.none.tmpl index 1becab4da..ba43380f0 100644 --- a/extensions/Voting/template/en/default/hook/global/field-descs-end.none.tmpl +++ b/extensions/Voting/template/en/default/hook/global/field-descs-end.none.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/hook/global/reason-descs-end.none.tmpl b/extensions/Voting/template/en/default/hook/global/reason-descs-end.none.tmpl index 3a1f5a189..9aedcd50c 100644 --- a/extensions/Voting/template/en/default/hook/global/reason-descs-end.none.tmpl +++ b/extensions/Voting/template/en/default/hook/global/reason-descs-end.none.tmpl @@ -14,10 +14,10 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] [% reason_descs.${constants.REL_VOTER} = "You voted for the ${terms.bug}." %] -[% watch_reason_descs.${constants.REL_VOTER} = +[% watch_reason_descs.${constants.REL_VOTER} = "You are watching a voter for the ${terms.bug}." %] diff --git a/extensions/Voting/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/Voting/template/en/default/hook/global/user-error-errors.html.tmpl index c2ff70728..057aa1d79 100644 --- a/extensions/Voting/template/en/default/hook/global/user-error-errors.html.tmpl +++ b/extensions/Voting/template/en/default/hook/global/user-error-errors.html.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/hook/search/form-after_freetext_fields.html.tmpl b/extensions/Voting/template/en/default/hook/search/form-after_freetext_fields.html.tmpl index dca1dba00..b91c14dfe 100644 --- a/extensions/Voting/template/en/default/hook/search/form-after_freetext_fields.html.tmpl +++ b/extensions/Voting/template/en/default/hook/search/form-after_freetext_fields.html.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/hook/search/search-report-select-rep_fields.html.tmpl b/extensions/Voting/template/en/default/hook/search/search-report-select-rep_fields.html.tmpl index ca74f6d2d..c58db3800 100644 --- a/extensions/Voting/template/en/default/hook/search/search-report-select-rep_fields.html.tmpl +++ b/extensions/Voting/template/en/default/hook/search/search-report-select-rep_fields.html.tmpl @@ -14,7 +14,7 @@ # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # - # Contributor(s): + # Contributor(s): # Max Kanat-Alexander <mkanat@bugzilla.org> #%] diff --git a/extensions/Voting/template/en/default/pages/voting.html.tmpl b/extensions/Voting/template/en/default/pages/voting.html.tmpl index 99026c0d5..5165d32c8 100644 --- a/extensions/Voting/template/en/default/pages/voting.html.tmpl +++ b/extensions/Voting/template/en/default/pages/voting.html.tmpl @@ -22,19 +22,19 @@ [% PROCESS global/variables.none.tmpl %] [% INCLUDE global/header.html.tmpl title = "Voting" %] -<p>[% terms.Bugzilla %] has a "voting" feature. Each product allows users to -have a certain number of votes. (Some products may not allow any, which means -you can't vote on things in those products at all.) With your vote, you -indicate which [% terms.bugs %] you think are the most important and -would like to see fixed. Note that voting is nowhere near as effective +<p>[% terms.Bugzilla %] has a "voting" feature. Each product allows users to +have a certain number of votes. (Some products may not allow any, which means +you can't vote on things in those products at all.) With your vote, you +indicate which [% terms.bugs %] you think are the most important and +would like to see fixed. Note that voting is nowhere near as effective as providing a fix yourself.</p> <p>Depending on how the administrator has configured the relevant product, you may be able to vote for the same [% terms.bug %] more than once. -Remember that you have a limited number of votes. When weighted voting -is allowed and a limited number of votes are available to you, you will -have to decide whether you want to distribute your votes among a large -number of [% terms.bugs %] indicating your minimal interest or focus on +Remember that you have a limited number of votes. When weighted voting +is allowed and a limited number of votes are available to you, you will +have to decide whether you want to distribute your votes among a large +number of [% terms.bugs %] indicating your minimal interest or focus on a few [% terms.bugs %] indicating your strong support for them. </p> @@ -55,8 +55,8 @@ a few [% terms.bugs %] indicating your strong support for them. fields. (If no such link appears, then voting may not be allowed in this [% terms.bug %]'s product.)</li> - <li>Indicate how many votes you want to give this [% terms.bug %]. This page - also displays how many votes you've given to other [% terms.bugs %], so you + <li>Indicate how many votes you want to give this [% terms.bug %]. This page + also displays how many votes you've given to other [% terms.bugs %], so you may rebalance your votes as necessary.</li> </ul> |