summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--template/en/default/search/boolean-charts.html.tmpl118
-rw-r--r--template/en/default/search/form.html.tmpl670
-rw-r--r--template/en/default/search/knob.html.tmpl95
-rw-r--r--template/en/default/search/search-advanced.html.tmpl831
-rw-r--r--template/en/default/search/search.html.tmpl831
5 files changed, 899 insertions, 1646 deletions
diff --git a/template/en/default/search/boolean-charts.html.tmpl b/template/en/default/search/boolean-charts.html.tmpl
new file mode 100644
index 000000000..2d25f91f0
--- /dev/null
+++ b/template/en/default/search/boolean-charts.html.tmpl
@@ -0,0 +1,118 @@
+<!-- 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>
+ #%]
+
+[% types = [
+ { name => "noop", description => "---" },
+ { name => "equals", description => "is equal to" },
+ { name => "notequals", description => "is not equal to" },
+ { name => "substring", description => "contains the string" },
+ { name => "casesubstring", description => "contains the string (exact case)" },
+ { name => "notsubstring", description => "does not contain the string" },
+ { name => "allwordssubstr", description => "contains all of the strings" },
+ { name => "anywordssubstr", description => "contains any of the strings" },
+ { name => "regexp", description => "contains regexp" },
+ { name => "notregexp", description => "does not contain regexp" },
+ { name => "lessthan", description => "is less than" },
+ { name => "greaterthan", description => "is greater than" },
+ { name => "anywords", description => "contains any of the words" },
+ { name => "allwords", description => "contains all of the words" },
+ { name => "nowords", description => "contains none of the words" },
+ { name => "changedbefore", description => "changed before" },
+ { name => "changedafter", description => "changed after" },
+ { name => "changedfrom", description => "changed from" },
+ { name => "changedto", description => "changed to" },
+ { name => "changedby", description => "changed by" } ] %]
+
+ <p>
+ <strong>
+ <a name="chart" href="queryhelp.cgi#advancedquerying">
+ Advanced Querying Using Boolean Charts</a>:
+ </strong>
+ </p>
+
+[%# Whoever wrote the original version of boolean charts had a seriously twisted mind %]
+
+[% jsmagic = "onclick=\"document.forms[0].action='query.cgi#chart'; document.forms[0].method='POST'; return 1;\"" %]
+
+[% FOREACH chart = default.charts %]
+ [% chartnum = loop.count - 1 %]
+ <table>
+ [% FOREACH row = chart %]
+ [% rownum = loop.count - 1 %]
+ <tr>
+ [% FOREACH col = row %]
+ [% colnum = loop.count - 1 %]
+ <td>
+ <select name="[% "field${chartnum}-${rownum}-${colnum}" %]">
+ [% FOREACH field = fields %]
+ <option value="[% field.name %]"
+ [%- " selected" IF field.name == col.field %]>[% field.description %]</option>
+ [% END %]
+ </select>
+
+ <select name="[% "type${chartnum}-${rownum}-${colnum}" %]">
+ [% FOREACH type = types %]
+ <option value="[% type.name %]"
+ [%- " selected" IF type.name == col.type %]>[% type.description %]</option>
+ [% END %]
+ </select>
+
+ <input name="[% "value${chartnum}-${rownum}-${colnum}" %]"
+ value="[% col.value FILTER html %]">
+ </td>
+
+ [% IF NOT col == row.last %]
+ <td align="center">
+ Or
+ </td>
+ [% ELSE %]
+ <td>
+ [% newor = colnum + 1 %]
+ <input type="submit" value="Or"
+ name="cmd-add[% "${chartnum}-${rownum}-${newor}" %]" [% $jsmagic %]>
+ </td>
+ [% END %]
+
+ [% END %]
+ </tr>
+
+ [% IF NOT row == chart.last %]
+ <tr>
+ <td>And</td>
+ </tr>
+ [% ELSE %]
+ <tr>
+ <td>
+ [% newand = rownum + 1; newchart = chartnum + 1 %]
+ <input type="submit" value="And"
+ name="cmd-add[% "${chartnum}-${newand}-0" %]"[% $jsmagic %]>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <input type="submit" value="Add another boolean chart"
+ name="cmd-add[% newchart %]-0-0" [% $jsmagic %]>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ </td>
+ </tr>
+ [% END %]
+
+ [% END %]
+ </table>
+ <hr>
+[% END %]
diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl
new file mode 100644
index 000000000..916039743
--- /dev/null
+++ b/template/en/default/search/form.html.tmpl
@@ -0,0 +1,670 @@
+<!-- 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 = componentsbyproduct.$p %]'[% item FILTER js %]', [%- END -%]];
+ vers[[% n %]] = [
+ [%- FOREACH item = versionsbyproduct.$p -%]'[% item FILTER js %]', [%- END -%]];
+ [% IF Param('usetargetmilestone') %]
+ tms[[% n %]] = [
+ [%- FOREACH item = milestonesbyproduct.$p %]'[% item FILTER js %]', [%- 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 getSelection(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 = getSelection(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 = getSelection(f.component, false, true);
+ var saved_vers = getSelection(f.version, false, true);
+ [% IF Param('usetargetmilestone') %]
+ var saved_tms = getSelection(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&#8217;t match the regexp" } ] %]
+
+[%# *** Summary *** %]
+
+<table>
+ <tr>
+ <th align="right">Summary:</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" 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 valign="bottom">
+ <th align="left">Product:</th>
+ <th align="left"><a href="describecomponents.cgi">Component</a>:</th>
+ <th align="left">Version:</th>
+
+ [% IF (Param("usetargetmilestone")) %]
+ <th align="left">Target:</th>
+ [% END %]
+ </tr>
+
+ <tr valign="top">
+
+ [%# Can't use the select block here because of onChange and the fact that
+ 'component' is a toolkit reserved word - we use 'component_' instead. %]
+ <td align="left">
+ <select name="product" multiple size="5" onChange="selectProduct(this.form);">
+ [% FOREACH p = product %]
+ <option value="[% p FILTER html %]"
+ [% " selected" IF lsearch(default.product, p) != -1 %]>
+ [% p FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+
+ <td align="left">
+ <select name="component" multiple size="5">
+ [% FOREACH c = component_ %]
+ <option value="[% c FILTER html %]"
+ [% " selected" IF lsearch(default.component, c) != -1 %]>
+ [% c FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+
+ [% PROCESS select sel = { name => 'version', size => 5 } %]
+
+ [% IF Param('usetargetmilestone') && target_milestone.size > 0 %]
+ [% PROCESS select sel = { name => 'target_milestone', size => 5 } %]
+ [% END %]
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+[%# *** Comment URL Whiteboard Keywords *** %]
+
+ [% FOREACH field = [
+ { name => "long_desc", description => "A&nbsp;comment" },
+ { name => "bug_file_loc", description => "The&nbsp;URL" },
+ { name => "status_whiteboard", description => "Whiteboard" } ] %]
+
+ [% 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" value="
+ [% default.${field.name}.0 FILTER html %]">
+ </td>
+ <td></td>
+ </tr>
+ [% END %]
+ [% END %]
+
+ [% IF have_keywords %]
+ <tr>
+ <th align="right"><a href="describekeywords.cgi">Keywords</a>:</th>
+ <td>
+ <select name="keywords_type">
+ [% FOREACH qv = [
+ { name => "anywords", description => "contains any of the keywords" },
+ { name => "allwords", description => "contains all 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" value="[% default.keywords.0 FILTER html %]">
+ </td>
+ </tr>
+ [% END %]
+</table>
+
+<hr>
+
+[%# *** Status Resolution Severity Priority Hardware OS *** %]
+
+<table>
+ <tr>
+ <th align="left"><a href="queryhelp.cgi#status">Status</a>:</th>
+ <th align="left"><a href="queryhelp.cgi#resolution">Resolution</a>:</th>
+ <th align="left"><a href="queryhelp.cgi#severity">Severity</a>:</th>
+ <th align="left"><a href="queryhelp.cgi#priority">Priority</a>:</th>
+ <th align="left"><a href="queryhelp.cgi#platform">Hardware</a>:</th>
+ <th align="left"><a href="queryhelp.cgi#opsys">OS</a>:</th>
+ </tr>
+
+ <tr valign="top">
+ [% PROCESS select sel = { name => 'bug_status', size => 7 } %]
+ [% PROCESS select sel = { name => 'resolution', size => 7 } %]
+ [% PROCESS select sel = { name => 'bug_severity', size => 7 } %]
+ [% PROCESS select sel = { name => 'priority', size => 7 } %]
+ [% PROCESS select sel = { name => 'rep_platform', size => 7 } %]
+ [% PROCESS select sel = { name => 'op_sys', size => 7 } %]
+ </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&#8217;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>
+ <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>
+</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 size="4">
+ [% FOREACH field = chfield %]
+ <option value="[% field FILTER html %]"
+ [% " selected" IF lsearch(default.chfield, field) != -1 %]>
+ [% 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>
+
+[%# Note: the <form> tag is unclosed at the end of this template %]
+
+[%############################################################################%]
+[%# Block for SELECT fields #%]
+[%############################################################################%]
+
+[% BLOCK select %]
+ <td align="left">
+ <select name="[% sel.name %]" 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>
+ </td>
+[% END %]
diff --git a/template/en/default/search/knob.html.tmpl b/template/en/default/search/knob.html.tmpl
new file mode 100644
index 000000000..beda930b3
--- /dev/null
+++ b/template/en/default/search/knob.html.tmpl
@@ -0,0 +1,95 @@
+<!-- 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>
+ #%]
+
+<table>
+ <tr>
+ <td colspan="2">
+
+ [% IF NOT userid %]
+ <input type="hidden" name="cmdtype" value="doit">
+ [% ELSE %]
+ <br>
+ <input type="radio" name="cmdtype" value="doit" checked> Run this query
+ <br>
+
+ [% IF namedqueries.size > 0 %]
+ <p>
+ <table cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ <input type="radio" name="cmdtype" value="editnamed">
+ Load my remembered query:
+ </td>
+ <td rowspan="3">
+ <select name="namedcmd">
+ [% FOREACH query = namedqueries %]
+ <option value="[% query FILTER html %]">[% query FILTER html %]</option>
+ [% END %]
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <input type="radio" name="cmdtype" value="runnamed">
+ Run my remembered query:
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <input type="radio" name="cmdtype" value="forgetnamed">
+ Forget my remembered query:
+ </td>
+ </tr>
+ </table>
+ </p>
+ [% END %]
+
+ <input type="radio" name="cmdtype" value="asdefault">
+ Remember this as my default query
+ <br>
+ <input type="radio" name="cmdtype" value="asnamed">
+ Remember this query, and name it:
+ <input type="text" name="newqueryname">
+ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" name="tofooter" value="1">
+ and put it in my page footer
+ <br>
+ [% END %]
+ <br>
+ <div>
+ Sort results by:
+ <select name="order">
+ [% FOREACH order = orders %]
+ <option value="[% order FILTER html %]"
+ [% " selected" IF default.order.0 == order %]>[% order FILTER html %]</option>
+ [% END %]
+ </select>
+
+ <input type="submit" value="[% button_name %]">
+ [% IF userdefaultquery %]
+ <p>
+ <a href="query.cgi?nukedefaultquery=1">
+ Set my default query back to the system default</a>
+ </p>
+ [% END %]
+ </div>
+ </td>
+ </tr>
+</table>
diff --git a/template/en/default/search/search-advanced.html.tmpl b/template/en/default/search/search-advanced.html.tmpl
index ec93e8592..b64470937 100644
--- a/template/en/default/search/search-advanced.html.tmpl
+++ b/template/en/default/search/search-advanced.html.tmpl
@@ -16,9 +16,7 @@
# 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>
+ # Contributor(s): Gervase Markham <gerv@gerv.net>
#%]
[% PROCESS global/header.html.tmpl
@@ -26,833 +24,20 @@
extra = " onLoad=\"selectProduct(document.forms['queryform']);\""
%]
-[%# Note: use Template comments and not JS ones here, to avoid bloating
- what we actually send to the browser %]
+[% button_name = "Search" %]
-<script language="JavaScript" type="text/javascript"> <!--
+[% PROCESS search/form.html.tmpl %]
-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 = componentsbyproduct.$p %]'[% item FILTER js %]', [%- END -%]];
- vers[[% n %]] = [
- [%- FOREACH item = versionsbyproduct.$p -%]'[% item FILTER js %]', [%- END -%]];
- [% IF Param('usetargetmilestone') %]
- tms[[% n %]] = [
- [%- FOREACH item = milestonesbyproduct.$p %]'[% item FILTER js %]', [%- 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 getSelection(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 = getSelection(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 = getSelection(f.component, false, true);
- var saved_vers = getSelection(f.version, false, true);
- [% IF Param('usetargetmilestone') %]
- var saved_tms = getSelection(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&#8217;t match the regexp" } ] %]
-
-<form method="get" action="buglist.cgi" name="queryform">
-
-[%# *** Summary *** %]
-
-<table>
- <tr>
- <th align="right">Summary:</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" value="[% default.short_desc.0 FILTER html %]">
- </td>
- <td>
- <input type="submit" value="Search">
- </td>
- </tr>
-
-[%# *** Product Component Version Target *** %]
-
- <tr>
- <td colspan="4">
- <table>
- <tr valign="bottom">
- <th align="left">Product:</th>
- <th align="left"><a href="describecomponents.cgi">Component</a>:</th>
- <th align="left">Version:</th>
-
- [% IF (Param("usetargetmilestone")) %]
- <th align="left">Target:</th>
- [% END %]
- </tr>
-
- <tr valign="top">
-
- [%# Can't use the select block here because of onChange and the fact that
- 'component' is a toolkit reserved word - we use 'component_' instead. %]
- <td align="left">
- <select name="product" multiple size="5" onChange="selectProduct(this.form);">
- [% FOREACH p = product %]
- <option value="[% p FILTER html %]"
- [% " selected" IF lsearch(default.product, p) != -1 %]>
- [% p FILTER html %]</option>
- [% END %]
- </select>
- </td>
-
- <td align="left">
- <select name="component" multiple size="5">
- [% FOREACH c = component_ %]
- <option value="[% c FILTER html %]"
- [% " selected" IF lsearch(default.component, c) != -1 %]>
- [% c FILTER html %]</option>
- [% END %]
- </select>
- </td>
-
- [% PROCESS select sel = { name => 'version', size => 5 } %]
-
- [% IF Param('usetargetmilestone') && target_milestone.size > 0 %]
- [% PROCESS select sel = { name => 'target_milestone', size => 5 } %]
- [% END %]
- </tr>
- </table>
- </td>
- </tr>
-
-[%# *** Comment URL Whiteboard Keywords *** %]
-
- [% FOREACH field = [
- { name => "long_desc", description => "A&nbsp;comment" },
- { name => "bug_file_loc", description => "The&nbsp;URL" },
- { name => "status_whiteboard", description => "Whiteboard" } ] %]
-
- [% 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" value="
- [% default.${field.name}.0 FILTER html %]">
- </td>
- <td></td>
- </tr>
- [% END %]
- [% END %]
-
- [% IF have_keywords %]
- <tr>
- <th align="right"><a href="describekeywords.cgi">Keywords</a>:</th>
- <td>
- <select name="keywords_type">
- [% FOREACH qv = [
- { name => "anywords", description => "contains any of the keywords" },
- { name => "allwords", description => "contains all 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" value="[% default.keywords.0 FILTER html %]">
- </td>
- </tr>
- [% END %]
-</table>
+[% PROCESS search/knob.html.tmpl %]
<hr>
-[%# *** Status Resolution Severity Priority Hardware OS *** %]
-
-<table>
- <tr>
- <th align="left"><a href="queryhelp.cgi#status">Status</a>:</th>
- <th align="left"><a href="queryhelp.cgi#resolution">Resolution</a>:</th>
- <th align="left"><a href="queryhelp.cgi#severity">Severity</a>:</th>
- <th align="left"><a href="queryhelp.cgi#priority">Priority</a>:</th>
- <th align="left"><a href="queryhelp.cgi#platform">Hardware</a>:</th>
- <th align="left"><a href="queryhelp.cgi#opsys">OS</a>:</th>
- </tr>
-
- <tr valign="top">
- [% PROCESS select sel = { name => 'bug_status', size => 7 } %]
- [% PROCESS select sel = { name => 'resolution', size => 7 } %]
- [% PROCESS select sel = { name => 'bug_severity', size => 7 } %]
- [% PROCESS select sel = { name => 'priority', size => 7 } %]
- [% PROCESS select sel = { name => 'rep_platform', size => 7 } %]
- [% PROCESS select sel = { name => 'op_sys', size => 7 } %]
- </tr>
-</table>
+[% PROCESS "search/boolean-charts.html.tmpl" %]
<p>
+ Give me a <a href="queryhelp.cgi">clue</a> about how to use this form.
+</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&#8217;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="20" 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>
- <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>
-</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 size="4">
- [% FOREACH field = chfield %]
- <option value="[% field FILTER html %]"
- [% " selected" IF lsearch(default.chfield, field) != -1 %]>
- [% 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>
-
-[%# *** Action Selection *** %]
-
- <tr>
- <td colspan="2">
-
- [% IF NOT userid %]
- <input type="hidden" name="cmdtype" value="doit">
- [% ELSE %]
- <br>
- <input type="radio" name="cmdtype" value="doit" checked> Run this query
- <br>
-
- [% IF namedqueries.size > 0 %]
- <p>
- <table cellspacing="0" cellpadding="0">
- <tr>
- <td>
- <input type="radio" name="cmdtype" value="editnamed">
- Load my remembered query:
- </td>
- <td rowspan="3">
- <select name="namedcmd">
- [% FOREACH query = namedqueries %]
- <option value="[% query FILTER html %]">[% query FILTER html %]</option>
- [% END %]
- </select>
- </td>
- </tr>
- <tr>
- <td>
- <input type="radio" name="cmdtype" value="runnamed">
- Run my remembered query:
- </td>
- </tr>
- <tr>
- <td>
- <input type="radio" name="cmdtype" value="forgetnamed">
- Forget my remembered query:
- </td>
- </tr>
- </table>
- </p>
- [% END %]
-
- <input type="radio" name="cmdtype" value="asdefault">
- Remember this as my default query
- <br>
- <input type="radio" name="cmdtype" value="asnamed">
- Remember this query, and name it:
- <input type="text" name="newqueryname">
- <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" name="tofooter" value="1">
- and put it in my page footer
- <br>
- [% END %]
- <br>
- <div>
- Sort results by:
- <select name="order">
- [% FOREACH order = orders %]
- <option value="[% order FILTER html %]"
- [% " selected" IF default.order.0 == order %]>[% order FILTER html %]</option>
- [% END %]
- </select>
-
- <input type="submit" value="Search">
- [% IF userdefaultquery %]
- <p>
- <a href="query.cgi?nukedefaultquery=1">
- Set my default query back to the system default</a>
- </p>
- [% END %]
- </div>
- </td>
- </tr>
-</table>
-
-[%# *** Boolean Charts *** %]
-
-<hr>
-
-[% types = [
- { name => "noop", description => "---" },
- { name => "equals", description => "is equal to" },
- { name => "notequals", description => "is not equal to" },
- { name => "substring", description => "contains the string" },
- { name => "casesubstring", description => "contains the string (exact case)" },
- { name => "notsubstring", description => "does not contain the string" },
- { name => "allwordssubstr", description => "contains all of the strings" },
- { name => "anywordssubstr", description => "contains any of the strings" },
- { name => "regexp", description => "contains regexp" },
- { name => "notregexp", description => "does not contain regexp" },
- { name => "lessthan", description => "is less than" },
- { name => "greaterthan", description => "is greater than" },
- { name => "anywords", description => "contains any of the words" },
- { name => "allwords", description => "contains all of the words" },
- { name => "nowords", description => "contains none of the words" },
- { name => "changedbefore", description => "changed before" },
- { name => "changedafter", description => "changed after" },
- { name => "changedfrom", description => "changed from" },
- { name => "changedto", description => "changed to" },
- { name => "changedby", description => "changed by" } ] %]
-
- <p>
- <strong>
- <a name="chart" href="queryhelp.cgi#advancedquerying">
- Advanced Querying Using Boolean Charts</a>:
- </strong>
- </p>
-
-[%# Whoever wrote the original version of boolean charts had a seriously twisted mind %]
-
-[% jsmagic = "onclick=\"document.forms[0].action='query.cgi#chart'; document.forms[0].method='POST'; return 1;\"" %]
-
-[% FOREACH chart = default.charts %]
- [% chartnum = loop.count - 1 %]
- <table>
- [% FOREACH row = chart %]
- [% rownum = loop.count - 1 %]
- <tr>
- [% FOREACH col = row %]
- [% colnum = loop.count - 1 %]
- <td>
- <select name="[% "field${chartnum}-${rownum}-${colnum}" %]">
- [% FOREACH field = fields %]
- <option value="[% field.name %]"
- [%- " selected" IF field.name == col.field %]>[% field.description %]</option>
- [% END %]
- </select>
-
- <select name="[% "type${chartnum}-${rownum}-${colnum}" %]">
- [% FOREACH type = types %]
- <option value="[% type.name %]"
- [%- " selected" IF type.name == col.type %]>[% type.description %]</option>
- [% END %]
- </select>
-
- <input name="[% "value${chartnum}-${rownum}-${colnum}" %]"
- value="[% col.value FILTER html %]">
- </td>
-
- [% IF NOT col == row.last %]
- <td align="center">
- Or
- </td>
- [% ELSE %]
- <td>
- [% newor = colnum + 1 %]
- <input type="submit" value="Or"
- name="cmd-add[% "${chartnum}-${rownum}-${newor}" %]" [% $jsmagic %]>
- </td>
- [% END %]
-
- [% END %]
- </tr>
-
- [% IF NOT row == chart.last %]
- <tr>
- <td>And</td>
- </tr>
- [% ELSE %]
- <tr>
- <td>
- [% newand = rownum + 1; newchart = chartnum + 1 %]
- <input type="submit" value="And"
- name="cmd-add[% "${chartnum}-${newand}-0" %]"[% $jsmagic %]>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
- <input type="submit" value="Add another boolean chart"
- name="cmd-add[% newchart %]-0-0" [% $jsmagic %]>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
- </td>
- </tr>
- [% END %]
-
- [% END %]
- </table>
- <hr>
-[% END %]
-
-<p>Give me a <a href="queryhelp.cgi">clue</a> about how to use this form.</p>
-
-</FORM>
+</form>
[% PROCESS global/footer.html.tmpl %]
-
-[%############################################################################%]
-[%# Block for SELECT fields #%]
-[%############################################################################%]
-
-[% BLOCK select %]
- <td align="left">
- <select name="[% sel.name %]" 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>
- </td>
-[% END %]
diff --git a/template/en/default/search/search.html.tmpl b/template/en/default/search/search.html.tmpl
index ec93e8592..b64470937 100644
--- a/template/en/default/search/search.html.tmpl
+++ b/template/en/default/search/search.html.tmpl
@@ -16,9 +16,7 @@
# 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>
+ # Contributor(s): Gervase Markham <gerv@gerv.net>
#%]
[% PROCESS global/header.html.tmpl
@@ -26,833 +24,20 @@
extra = " onLoad=\"selectProduct(document.forms['queryform']);\""
%]
-[%# Note: use Template comments and not JS ones here, to avoid bloating
- what we actually send to the browser %]
+[% button_name = "Search" %]
-<script language="JavaScript" type="text/javascript"> <!--
+[% PROCESS search/form.html.tmpl %]
-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 = componentsbyproduct.$p %]'[% item FILTER js %]', [%- END -%]];
- vers[[% n %]] = [
- [%- FOREACH item = versionsbyproduct.$p -%]'[% item FILTER js %]', [%- END -%]];
- [% IF Param('usetargetmilestone') %]
- tms[[% n %]] = [
- [%- FOREACH item = milestonesbyproduct.$p %]'[% item FILTER js %]', [%- 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 getSelection(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 = getSelection(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 = getSelection(f.component, false, true);
- var saved_vers = getSelection(f.version, false, true);
- [% IF Param('usetargetmilestone') %]
- var saved_tms = getSelection(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&#8217;t match the regexp" } ] %]
-
-<form method="get" action="buglist.cgi" name="queryform">
-
-[%# *** Summary *** %]
-
-<table>
- <tr>
- <th align="right">Summary:</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" value="[% default.short_desc.0 FILTER html %]">
- </td>
- <td>
- <input type="submit" value="Search">
- </td>
- </tr>
-
-[%# *** Product Component Version Target *** %]
-
- <tr>
- <td colspan="4">
- <table>
- <tr valign="bottom">
- <th align="left">Product:</th>
- <th align="left"><a href="describecomponents.cgi">Component</a>:</th>
- <th align="left">Version:</th>
-
- [% IF (Param("usetargetmilestone")) %]
- <th align="left">Target:</th>
- [% END %]
- </tr>
-
- <tr valign="top">
-
- [%# Can't use the select block here because of onChange and the fact that
- 'component' is a toolkit reserved word - we use 'component_' instead. %]
- <td align="left">
- <select name="product" multiple size="5" onChange="selectProduct(this.form);">
- [% FOREACH p = product %]
- <option value="[% p FILTER html %]"
- [% " selected" IF lsearch(default.product, p) != -1 %]>
- [% p FILTER html %]</option>
- [% END %]
- </select>
- </td>
-
- <td align="left">
- <select name="component" multiple size="5">
- [% FOREACH c = component_ %]
- <option value="[% c FILTER html %]"
- [% " selected" IF lsearch(default.component, c) != -1 %]>
- [% c FILTER html %]</option>
- [% END %]
- </select>
- </td>
-
- [% PROCESS select sel = { name => 'version', size => 5 } %]
-
- [% IF Param('usetargetmilestone') && target_milestone.size > 0 %]
- [% PROCESS select sel = { name => 'target_milestone', size => 5 } %]
- [% END %]
- </tr>
- </table>
- </td>
- </tr>
-
-[%# *** Comment URL Whiteboard Keywords *** %]
-
- [% FOREACH field = [
- { name => "long_desc", description => "A&nbsp;comment" },
- { name => "bug_file_loc", description => "The&nbsp;URL" },
- { name => "status_whiteboard", description => "Whiteboard" } ] %]
-
- [% 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" value="
- [% default.${field.name}.0 FILTER html %]">
- </td>
- <td></td>
- </tr>
- [% END %]
- [% END %]
-
- [% IF have_keywords %]
- <tr>
- <th align="right"><a href="describekeywords.cgi">Keywords</a>:</th>
- <td>
- <select name="keywords_type">
- [% FOREACH qv = [
- { name => "anywords", description => "contains any of the keywords" },
- { name => "allwords", description => "contains all 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" value="[% default.keywords.0 FILTER html %]">
- </td>
- </tr>
- [% END %]
-</table>
+[% PROCESS search/knob.html.tmpl %]
<hr>
-[%# *** Status Resolution Severity Priority Hardware OS *** %]
-
-<table>
- <tr>
- <th align="left"><a href="queryhelp.cgi#status">Status</a>:</th>
- <th align="left"><a href="queryhelp.cgi#resolution">Resolution</a>:</th>
- <th align="left"><a href="queryhelp.cgi#severity">Severity</a>:</th>
- <th align="left"><a href="queryhelp.cgi#priority">Priority</a>:</th>
- <th align="left"><a href="queryhelp.cgi#platform">Hardware</a>:</th>
- <th align="left"><a href="queryhelp.cgi#opsys">OS</a>:</th>
- </tr>
-
- <tr valign="top">
- [% PROCESS select sel = { name => 'bug_status', size => 7 } %]
- [% PROCESS select sel = { name => 'resolution', size => 7 } %]
- [% PROCESS select sel = { name => 'bug_severity', size => 7 } %]
- [% PROCESS select sel = { name => 'priority', size => 7 } %]
- [% PROCESS select sel = { name => 'rep_platform', size => 7 } %]
- [% PROCESS select sel = { name => 'op_sys', size => 7 } %]
- </tr>
-</table>
+[% PROCESS "search/boolean-charts.html.tmpl" %]
<p>
+ Give me a <a href="queryhelp.cgi">clue</a> about how to use this form.
+</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&#8217;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="20" 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>
- <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>
-</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 size="4">
- [% FOREACH field = chfield %]
- <option value="[% field FILTER html %]"
- [% " selected" IF lsearch(default.chfield, field) != -1 %]>
- [% 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>
-
-[%# *** Action Selection *** %]
-
- <tr>
- <td colspan="2">
-
- [% IF NOT userid %]
- <input type="hidden" name="cmdtype" value="doit">
- [% ELSE %]
- <br>
- <input type="radio" name="cmdtype" value="doit" checked> Run this query
- <br>
-
- [% IF namedqueries.size > 0 %]
- <p>
- <table cellspacing="0" cellpadding="0">
- <tr>
- <td>
- <input type="radio" name="cmdtype" value="editnamed">
- Load my remembered query:
- </td>
- <td rowspan="3">
- <select name="namedcmd">
- [% FOREACH query = namedqueries %]
- <option value="[% query FILTER html %]">[% query FILTER html %]</option>
- [% END %]
- </select>
- </td>
- </tr>
- <tr>
- <td>
- <input type="radio" name="cmdtype" value="runnamed">
- Run my remembered query:
- </td>
- </tr>
- <tr>
- <td>
- <input type="radio" name="cmdtype" value="forgetnamed">
- Forget my remembered query:
- </td>
- </tr>
- </table>
- </p>
- [% END %]
-
- <input type="radio" name="cmdtype" value="asdefault">
- Remember this as my default query
- <br>
- <input type="radio" name="cmdtype" value="asnamed">
- Remember this query, and name it:
- <input type="text" name="newqueryname">
- <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" name="tofooter" value="1">
- and put it in my page footer
- <br>
- [% END %]
- <br>
- <div>
- Sort results by:
- <select name="order">
- [% FOREACH order = orders %]
- <option value="[% order FILTER html %]"
- [% " selected" IF default.order.0 == order %]>[% order FILTER html %]</option>
- [% END %]
- </select>
-
- <input type="submit" value="Search">
- [% IF userdefaultquery %]
- <p>
- <a href="query.cgi?nukedefaultquery=1">
- Set my default query back to the system default</a>
- </p>
- [% END %]
- </div>
- </td>
- </tr>
-</table>
-
-[%# *** Boolean Charts *** %]
-
-<hr>
-
-[% types = [
- { name => "noop", description => "---" },
- { name => "equals", description => "is equal to" },
- { name => "notequals", description => "is not equal to" },
- { name => "substring", description => "contains the string" },
- { name => "casesubstring", description => "contains the string (exact case)" },
- { name => "notsubstring", description => "does not contain the string" },
- { name => "allwordssubstr", description => "contains all of the strings" },
- { name => "anywordssubstr", description => "contains any of the strings" },
- { name => "regexp", description => "contains regexp" },
- { name => "notregexp", description => "does not contain regexp" },
- { name => "lessthan", description => "is less than" },
- { name => "greaterthan", description => "is greater than" },
- { name => "anywords", description => "contains any of the words" },
- { name => "allwords", description => "contains all of the words" },
- { name => "nowords", description => "contains none of the words" },
- { name => "changedbefore", description => "changed before" },
- { name => "changedafter", description => "changed after" },
- { name => "changedfrom", description => "changed from" },
- { name => "changedto", description => "changed to" },
- { name => "changedby", description => "changed by" } ] %]
-
- <p>
- <strong>
- <a name="chart" href="queryhelp.cgi#advancedquerying">
- Advanced Querying Using Boolean Charts</a>:
- </strong>
- </p>
-
-[%# Whoever wrote the original version of boolean charts had a seriously twisted mind %]
-
-[% jsmagic = "onclick=\"document.forms[0].action='query.cgi#chart'; document.forms[0].method='POST'; return 1;\"" %]
-
-[% FOREACH chart = default.charts %]
- [% chartnum = loop.count - 1 %]
- <table>
- [% FOREACH row = chart %]
- [% rownum = loop.count - 1 %]
- <tr>
- [% FOREACH col = row %]
- [% colnum = loop.count - 1 %]
- <td>
- <select name="[% "field${chartnum}-${rownum}-${colnum}" %]">
- [% FOREACH field = fields %]
- <option value="[% field.name %]"
- [%- " selected" IF field.name == col.field %]>[% field.description %]</option>
- [% END %]
- </select>
-
- <select name="[% "type${chartnum}-${rownum}-${colnum}" %]">
- [% FOREACH type = types %]
- <option value="[% type.name %]"
- [%- " selected" IF type.name == col.type %]>[% type.description %]</option>
- [% END %]
- </select>
-
- <input name="[% "value${chartnum}-${rownum}-${colnum}" %]"
- value="[% col.value FILTER html %]">
- </td>
-
- [% IF NOT col == row.last %]
- <td align="center">
- Or
- </td>
- [% ELSE %]
- <td>
- [% newor = colnum + 1 %]
- <input type="submit" value="Or"
- name="cmd-add[% "${chartnum}-${rownum}-${newor}" %]" [% $jsmagic %]>
- </td>
- [% END %]
-
- [% END %]
- </tr>
-
- [% IF NOT row == chart.last %]
- <tr>
- <td>And</td>
- </tr>
- [% ELSE %]
- <tr>
- <td>
- [% newand = rownum + 1; newchart = chartnum + 1 %]
- <input type="submit" value="And"
- name="cmd-add[% "${chartnum}-${newand}-0" %]"[% $jsmagic %]>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
- <input type="submit" value="Add another boolean chart"
- name="cmd-add[% newchart %]-0-0" [% $jsmagic %]>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
- </td>
- </tr>
- [% END %]
-
- [% END %]
- </table>
- <hr>
-[% END %]
-
-<p>Give me a <a href="queryhelp.cgi">clue</a> about how to use this form.</p>
-
-</FORM>
+</form>
[% PROCESS global/footer.html.tmpl %]
-
-[%############################################################################%]
-[%# Block for SELECT fields #%]
-[%############################################################################%]
-
-[% BLOCK select %]
- <td align="left">
- <select name="[% sel.name %]" 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>
- </td>
-[% END %]