gerv%gerv.net 85270d5c9a Bug 181047 - Change non-output templates to have a ctype of "none". Patch by gerv; r=bbaetz, a=justdave.
git-svn-id: svn://10.0.0.236/trunk@135878 18797224-902f-48f8-a5cc-f745e15eee43
2003-01-06 07:56:28 +00:00

781 lines
24 KiB
Cheetah

<!-- 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): Chris Lahey <clahey@ximian.com> [javascript fixes]
# Christian Reis <kiko@async.com.br> [javascript rewrite]
# Gervase Markham <gerv@gerv.net>
#%]
[%# Note: use Template comments and not JS ones here, to avoid bloating
what we actually send to the browser %]
<script language="JavaScript" type="text/javascript"> <!--
var first_load = true; [%# is this the first time we load the page? %]
var last_sel = new Array(); [%# caches last selection %]
var cpts = new Array();
var vers = new Array();
[% IF Param('usetargetmilestone') %]
var tms = new Array();
[% END %]
[%# Create three arrays of components, versions and target milestones, indexed
# numerically according to the product they refer to. #%]
[% n = 0 %]
[% FOREACH p = product %]
cpts[[% n %]] = [
[%- FOREACH item = p.components %]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
vers[[% n %]] = [
[%- FOREACH item = p.versions -%]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
[% IF Param('usetargetmilestone') %]
tms[[% n %]] = [
[%- FOREACH item = p.milestones %]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
[% END %]
[% n = n+1 %]
[% END %]
[%# updateSelect(array, sel, target, merging)
#
# Adds to the target select object all elements in array that
# correspond to the elements selected in source.
# - array should be a array of arrays, indexed by number. the
# array should contain the elements that correspond to that
# product.
# - sel is a list of selected items, either whole or a diff
# depending on merging.
# - target should be the target select object.
# - merging (boolean) determines if we are mergine in a diff or
# substituting the whole selection. a diff is used to optimize adding
# selections.
#
# Example (compsel is a select form control)
#
# var components = Array();
# components[1] = [ 'ComponentA', 'ComponentB' ];
# components[2] = [ 'ComponentC', 'ComponentD' ];
# source = [ 2 ];
# updateSelect(components, source, compsel, 0, 0);
#
# would clear compsel and add 'ComponentC' and 'ComponentD' to it.
#
%]
function updateSelect(array, sel, target, merging) {
var i, item;
[%# If we have no versions/components/milestones %]
if (array.length < 1) {
target.options.length = 0;
return false;
}
if (merging) {
[%# array merging/sorting in the case of multiple selections %]
[%# merge in the current options with the first selection %]
item = merge_arrays(array[sel[0]], target.options, 1);
[%# merge the rest of the selection with the results %]
for (i = 1 ; i < sel.length ; i++) {
item = merge_arrays(array[sel[i]], item, 0);
}
} else if ( sel.length > 1 ) {
[%# here we micro-optimize for two arrays to avoid merging with a
null array %]
item = merge_arrays(array[sel[0]],array[sel[1]], 0);
[%# merge the arrays. not very good for multiple selections. %]
for (i = 2; i < sel.length; i++) {
item = merge_arrays(item, array[sel[i]], 0);
}
} else { [%# single item in selection, just get me the list %]
item = array[sel[0]];
}
[%# clear select %]
target.options.length = 0;
[%# load elements of list into select %]
for (i = 0; i < item.length; i++) {
target.options[i] = new Option(item[i], item[i]);
}
return true;
}
[%# Returns elements in a that are not in b.
# NOT A REAL DIFF: does not check the reverse.
# - a,b: arrays of values to be compare. %]
function fake_diff_array(a, b) {
var newsel = new Array();
var found = false;
[%# do a boring array diff to see who's new %]
for (var ia in a) {
for (var ib in b) {
if (a[ia] == b[ib]) {
found = true;
}
}
if (!found) {
newsel[newsel.length] = a[ia];
}
found = false;
}
return newsel;
}
[%# takes two arrays and sorts them by string, returning a new, sorted
# array. the merge removes dupes, too.
# - a, b: arrays to be merge.
# - b_is_select: if true, then b is actually an optionitem and as
# such we need to use item.value on it. %]
function merge_arrays(a, b, b_is_select) {
var pos_a = 0;
var pos_b = 0;
var ret = new Array();
var bitem, aitem;
[%# iterate through both arrays and add the larger item to the return
list. remove dupes, too. Use toLowerCase to provide
case-insensitivity. %]
while ((pos_a < a.length) && (pos_b < b.length)) {
if (b_is_select) {
bitem = b[pos_b].value;
} else {
bitem = b[pos_b];
}
aitem = a[pos_a];
[%# smaller item in list a %]
if (aitem.toLowerCase() < bitem.toLowerCase()) {
ret[ret.length] = aitem;
pos_a++;
} else {
[%# smaller item in list b %]
if (aitem.toLowerCase() > bitem.toLowerCase()) {
ret[ret.length] = bitem;
pos_b++;
} else {
[%# list contents are equal, inc both counters. %]
ret[ret.length] = aitem;
pos_a++;
pos_b++;
}
}
}
[%# catch leftovers here. these sections are ugly code-copying. %]
if (pos_a < a.length) {
for (; pos_a < a.length ; pos_a++) {
ret[ret.length] = a[pos_a];
}
}
if (pos_b < b.length) {
for (; pos_b < b.length; pos_b++) {
if (b_is_select) {
bitem = b[pos_b].value;
} else {
bitem = b[pos_b];
}
ret[ret.length] = bitem;
}
}
return ret;
}
[%# Returns an array of indexes or values from a select form control.
# - control: select control from which to find selections
# - findall: boolean, store all options when true or just the selected
# indexes
# - want_values: boolean; we store values when true and indexes when
# false %]
function get_selection(control, findall, want_values) {
var ret = new Array();
if ((!findall) && (control.selectedIndex == -1)) {
return ret;
}
for (var i=0; i<control.length; i++) {
if (findall || control.options[i].selected) {
ret[ret.length] = want_values ? control.options[i].value : i;
}
}
return ret;
}
[%# Selects items in control that have index defined in sel
# - control: SELECT control to be restored
# - selnames: array of indexes in select form control %]
function restoreSelection(control, selnames) {
[%# right. this sucks. but I see no way to avoid going through the
# list and comparing to the contents of the control. %]
for (var j=0; j < selnames.length; j++) {
for (var i=0; i < control.options.length; i++) {
if (control.options[i].value == selnames[j]) {
control.options[i].selected = true;
}
}
}
}
[%# selectProduct reads the selection from f.product and updates
# f.version, component and target_milestone accordingly.
# - f: a form containing product, component, varsion and
# target_milestone select boxes.
# globals (3vil!):
# - cpts, vers, tms: array of arrays, indexed by product name. the
# subarrays contain a list of names to be fed to the respective
# selectboxes. For bugzilla, these are generated with perl code
# at page start.
# - first_load: boolean, specifying if it is the first time we load
# the query page.
# - last_sel: saves our last selection list so we know what has
# changed, and optimize for additions. %]
function selectProduct(f) {
[%# this is to avoid handling events that occur before the form
itself is ready, which could happen in buggy browsers. %]
if ((!f) || (!f.product)) {
return;
}
[%# if this is the first load and nothing is selected, no need to
merge and sort all components; perl gives it to us sorted. %]
if ((first_load) && (f.product.selectedIndex == -1)) {
first_load = false;
return;
}
[%# turn first_load off. this is tricky, since it seems to be
redundant with the above clause. It's not: if when we first load
the page there is _one_ element selected, it won't fall into that
clause, and first_load will remain 1. Then, if we unselect that
item, selectProduct will be called but the clause will be valid
(since selectedIndex == -1), and we will return - incorrectly -
without merge/sorting. %]
first_load = false;
[%# - sel keeps the array of products we are selected.
- merging says if it is a full list or just a list of products that
were added to the current selection. %]
var merging = false;
var sel = Array();
[%# if nothing selected, pick all %]
var findall = f.product.selectedIndex == -1;
sel = get_selection(f.product, findall, false);
if (!findall) {
[%# save sel for the next invocation of selectProduct() %]
var tmp = sel;
[%# this is an optimization: if we have just added products to an
existing selection, no need to clear the form controls and add
everybody again; just merge the new ones with the existing
options. %]
if ((last_sel.length > 0) && (last_sel.length < sel.length)) {
sel = fake_diff_array(sel, last_sel);
merging = true;
}
last_sel = tmp;
}
[%# save original options selected %]
var saved_cpts = get_selection(f.component, false, true);
var saved_vers = get_selection(f.version, false, true);
[% IF Param('usetargetmilestone') %]
var saved_tms = get_selection(f.target_milestone, false, true);
[% END %]
[%# do the actual fill/update, reselect originally selected options %]
updateSelect(cpts, sel, f.component, merging);
restoreSelection(f.component, saved_cpts);
updateSelect(vers, sel, f.version, merging);
restoreSelection(f.version, saved_vers);
[% IF Param('usetargetmilestone') %]
updateSelect(tms, sel, f.target_milestone, merging);
restoreSelection(f.target_milestone, saved_tms);
[% END %]
}
// -->
</script>
[% query_variants = [
{ value => "allwordssubstr", description => "contains all of the words/strings" },
{ value => "anywordssubstr", description => "contains any of the words/strings" },
{ value => "substring", description => "contains the string" },
{ value => "casesubstring", description => "contains the string (exact case)" },
{ value => "allwords", description => "contains all of the words" },
{ value => "anywords", description => "contains any of the words" },
{ value => "regexp", description => "matches the regexp" },
{ value => "notregexp", description => "doesn't match the regexp" } ] %]
[% PROCESS "global/field-descs.none.tmpl" %]
[%# If we resubmit to ourselves, we need to know if we are using a format. %]
<input type="hidden" name="query_format" value="[% format %]">
[%# *** Summary *** %]
<table>
<tr>
<th align="right"><u>S</u>ummary:</th>
<td>
<select name="short_desc_type">
[% FOREACH qv = query_variants %]
<option value="[% qv.value %]"
[% " selected" IF default.short_desc_type.0 == qv.value %]>[% qv.description %]</option>
[% END %]
</select>
</td>
<td>
<input name="short_desc" size="40" accesskey="s"
value="[% default.short_desc.0 FILTER html %]">
</td>
<td>
<input type="submit" value="[% button_name %]">
</td>
</tr>
[%# *** Product Component Version Target *** %]
<tr>
<td colspan="4">
<table>
<tr>
<td valign="top">
<table>
<tr valign="bottom">
<th align="left"><u>P</u>roduct:</th>
</tr>
<tr valign="top">
[%# Can't use the select block here because of the onChange %]
<td align="left">
<label for="product" accesskey="p">
<select name="product" multiple="multiple" size="5" id="product"
onchange="selectProduct(this.form);">
[% FOREACH p = product %]
<option value="[% p.name FILTER html %]"
[% " selected" IF lsearch(default.product, p.name) != -1 %]>
[% p.name FILTER html %]</option>
[% END %]
</select>
</label>
</td>
</tr>
</table>
</td>
<td valign="top">
<table>
<tr valign="bottom">
<th align="left">
<a href="describecomponents.cgi">Co<u>m</u>ponent</a>:
</th>
</tr>
<tr valign="top">
[%# Can't use the select block here because 'component' is a toolkit
reserved word - we use 'component_' instead. %]
<td align="left">
<label for="component" accesskey="m">
<select name="component" id="component"
multiple="multiple" size="5">
[% FOREACH c = component_ %]
<option value="[% c FILTER html %]"
[% " selected" IF lsearch(default.component, c) != -1 %]>
[% c FILTER html %]</option>
[% END %]
</select>
</label>
</td>
</tr>
</table>
</td>
<td valign="top">
<table>
<tr valign="bottom">
<th align="left"><u>V</u>ersion:</th>
</tr>
<tr valign="top">
[% PROCESS select sel = { name => 'version',
size => 5,
accesskey => 'v' } %]
</tr>
</table>
</td>
[% IF Param('usetargetmilestone') %]
<td valign="top">
<table>
<tr valign="bottom">
<th align="left"><u>T</u>arget:</th>
</tr>
<tr valign="top">
[% PROCESS select sel = { name => 'target_milestone',
size => 5,
accesskey => 't' } %]
</tr>
</table>
</td>
[% END %]
</tr>
</table>
</td>
</tr>
[%# *** Comment URL Whiteboard Keywords *** %]
[% FOREACH field = [
{ name => "long_desc", description => "A&nbsp;<u>C</u>omment",
accesskey => 'c' },
{ name => "bug_file_loc", description => "The&nbsp;<u>U</u>RL",
accesskey => 'u' },
{ name => "status_whiteboard", description => "<u>W</u>hiteboard",
accesskey => 'w' } ] %]
[% UNLESS field.name == 'status_whiteboard' AND NOT Param('usestatuswhiteboard') %]
<tr>
<th align="right">[% field.description %]:</th>
<td>
<select name="[% field.name %]_type">
[% FOREACH qv = query_variants %]
[% type = "${field.name}_type" %]
<option value="[% qv.value %]"
[% " selected" IF default.$type.0 == qv.value %]>[% qv.description %]</option>
[% END %]
</select>
</td>
<td><input name="[% field.name %]" size="40"
accesskey="[% field.accesskey %]"
value="[% default.${field.name}.0 FILTER html %]">
</td>
<td></td>
</tr>
[% END %]
[% END %]
[% IF have_keywords %]
<tr>
<th align="right">
<a href="describekeywords.cgi"><u>K</u>eywords</a>:
</th>
<td>
<select name="keywords_type">
[% FOREACH qv = [
{ name => "allwords", description => "contains all of the keywords" },
{ name => "anywords", description => "contains any of the keywords" },
{ name => "nowords", description => "contains none of the keywords" } ] %]
<option value="[% qv.name %]"
[% " selected" IF default.keywords_type.0 == qv.name %]>
[% qv.description %]</option>
[% END %]
</select>
</td>
<td>
<input name="keywords" size="40" accesskey="k"
value="[% default.keywords.0 FILTER html %]">
</td>
</tr>
[% END %]
</table>
<hr>
[%# *** Status Resolution Severity Priority Hardware OS *** %]
<table>
<tr>
<td>
<table>
<tr>
<th align="left"><a href="queryhelp.cgi#status">St<u>a</u>tus</a>:</th>
</tr>
<tr valign="top">
[% PROCESS select sel = { name => 'bug_status',
size => 7,
accesskey => 'a' } %]
</tr>
</table>
</td>
<td>
<table>
<tr>
<th align="left">
<a href="queryhelp.cgi#resolution"><u>R</u>esolution</a>:
</th>
</tr>
<tr valign="top">
[% PROCESS select sel = { name => 'resolution',
size => 7,
accesskey => 'r' } %]
</tr>
</table>
</td>
<td>
<table>
<tr>
<th align="left"><a href="queryhelp.cgi#severity">S<u>e</u>verity</a>:</th>
</tr>
<tr valign="top">
[% PROCESS select sel = { name => 'bug_severity',
size => 7,
accesskey => 'e' } %]
</tr>
</table>
</td>
<td>
<table>
<tr>
<th align="left"><a href="queryhelp.cgi#priority">Pr<u>i</u>ority</a>:</th>
</tr>
<tr valign="top">
[% PROCESS select sel = { name => 'priority',
size => 7,
accesskey => 'i' } %]
</tr>
</table>
</td>
<td>
<table>
<tr>
<th align="left"><a href="queryhelp.cgi#platform"><u>H</u>ardware</a>:</th>
</tr>
<tr valign="top">
[% PROCESS select sel = { name => 'rep_platform',
size => 7,
accesskey => 'h' } %]
</tr>
</table>
</td>
<td>
<table>
<tr>
<th align="left"><a href="queryhelp.cgi#opsys"><u>O</u>S</a>:</th>
</tr>
<tr valign="top">
[% PROCESS select sel = { name => 'op_sys',
size => 7,
accesskey => 'o' } %]
</tr>
</table>
</td>
</tr>
</table>
<p>
[%# *** Email Numbering Votes *** %]
<table>
<tr>
<td>
<fieldset>
<legend>
<strong>
<a href="queryhelp.cgi#peopleinvolved">Email</a> and Numbering
</strong>
</legend>
<table>
<tr>
[% FOREACH n = [1, 2] %]
<td>
<table cellspacing="0" cellpadding="0">
<tr>
<td>
Any of:
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="emailassigned_to[% n %]"
id="emailassigned_to[% n %]" value="1"
[% " checked" IF default.emailassigned_to.$n %]>
<label for="emailassigned_to[% n %]">
bug owner
</label>
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="emailreporter[% n %]"
id="emailreporter[% n %]" value="1"
[% " checked" IF default.emailreporter.$n %]>
<label for="emailreporter[% n %]">
reporter
</label>
</td>
</tr>
[% IF Param('useqacontact') %]
<tr>
<td>
<input type="checkbox" name="emailqa_contact[% n %]"
id="emailqa_contact[% n %]" value="1"
[% " checked" IF default.emailqa_contact.$n %]>
<label for="emailqa_contact[% n %]">
QA contact
</label>
</td>
</tr>
[% END %]
<tr>
<td>
<input type="checkbox" name="emailcc[% n %]"
id="emailcc[% n %]" value="1"
[% " checked" IF default.emailcc.$n %]>
<label for="emailcc[% n %]">
CC list member
</label>
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="emaillongdesc[% n %]"
id="emaillongdesc[% n %]" value="1"
[% " checked" IF default.emaillongdesc.$n %]>
<label for="emaillongdesc[% n %]">
commenter
</label>
</td>
</tr>
<tr>
<td>
<select name="emailtype[% n %]">
[% FOREACH qv = [
{ name => "substring", description => "contains" },
{ name => "exact", description => "is" },
{ name => "regexp", description => "matches regexp" },
{ name => "notregexp", description => "doesn't match regexp" } ] %]
<option value="[% qv.name %]"
[% " selected" IF default.emailtype.$n == qv.name %]>[% qv.description %]</option>
[% END %]
</select>
</td>
</tr>
<tr>
<td>
<input name="email[% n %]" size="25" value="[% default.email.$n FILTER html %]">
</td>
</tr>
</table>
</td>
[% END %]
</tr>
</table>
<hr>
<table>
<tr>
<td>
<select name="bugidtype">
<option value="include"[% " selected" IF default.bugidtype.0 == "include" %]>Only include</option>
<option value="exclude"[% " selected" IF default.bugidtype.0 == "exclude" %]>Exclude</option>
</select>
bugs numbered:
</td>
<td>
<input type="text" name="bug_id" value="[% default.bug_id.0 FILTER html %]" size="20">
</td>
</tr>
<tr>
<td></td>
<td>(comma-separated list)</td>
</tr>
[% IF Param('usevotes') %]
<tr>
<td align="right">
Only bugs with at least:
</td>
<td>
<input name="votes" size="3" value="[% default.votes.0 FILTER html %]"> votes
</td>
</tr>
[% END %]
</table>
</fieldset>
</td>
[%# *** Bug Changes *** %]
<td valign="top">
<fieldset>
<legend><strong>Bug Changes</strong></legend>
<dl>
<dt>Only bugs changed in the last </dt>
<dd><input name="changedin" size="3" value="[% default.changedin.0 FILTER html %]"> days</dd>
</dl>
<dl>
<dt>Only bugs where any of the fields</dt>
<dd>
<select name="chfield" multiple="multiple" size="4">
[% FOREACH field = chfield %]
<option value="[% field FILTER html %]"
[% " selected" IF lsearch(default.chfield, field) != -1 %]>
[% (field_descs.$field || field) FILTER html %]</option>
[% END %]
</select>
</dd>
<dt>were changed between</dt>
<dd>
<input name="chfieldfrom" size="10" value="[% default.chfieldfrom.0 FILTER html %]">
and <input name="chfieldto" size="10" value="[% default.chfieldto.0 FILTER html %]">
<br>(YYYY-MM-DD)
</dd>
<dt>to this value: (optional)</dt>
<dd>
<input name="chfieldvalue" size="20" value="[% default.chfieldvalue.0 FILTER html %]">
</dd>
</dl>
</fieldset>
</td>
</tr>
</table>
[%############################################################################%]
[%# Block for SELECT fields #%]
[%############################################################################%]
[% BLOCK select %]
<td align="left">
<label for="[% sel.name %]" accesskey="[% sel.accesskey %]">
<select name="[% sel.name %]" id="[% sel.name %]"
multiple="multiple" size="[% sel.size %]">
[% FOREACH name = ${sel.name} %]
<option value="[% name FILTER html %]"
[% " selected" IF lsearch(default.${sel.name}, name) != -1 %]>
[% name FILTER html %]</option>
[% END %]
</select>
</label>
</td>
[% END %]