summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/Search/Quicksearch.pm499
-rw-r--r--QUICKSTART4
-rwxr-xr-xbuglist.cgi10
-rwxr-xr-xchecksetup.pl8
-rw-r--r--defparams.pl11
-rw-r--r--docs/xml/security.xml10
-rw-r--r--docs/xml/using.xml7
-rw-r--r--localconfig.js75
-rw-r--r--quicksearch.html151
-rw-r--r--quicksearch.js740
-rw-r--r--quicksearchhack.html357
-rw-r--r--skins/standard/global.css7
-rw-r--r--template/en/default/config.js.tmpl3
-rw-r--r--template/en/default/global/useful-links.html.tmpl11
-rw-r--r--template/en/default/index.html.tmpl31
-rw-r--r--template/en/default/pages/quicksearch.html.tmpl190
-rw-r--r--template/en/default/pages/quicksearchhack.html.tmpl377
-rw-r--r--template/en/default/sidebar.xul.tmpl8
18 files changed, 1118 insertions, 1381 deletions
diff --git a/Bugzilla/Search/Quicksearch.pm b/Bugzilla/Search/Quicksearch.pm
new file mode 100644
index 000000000..9f6724507
--- /dev/null
+++ b/Bugzilla/Search/Quicksearch.pm
@@ -0,0 +1,499 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# Contributor(s): C. Begle
+# Jesse Ruderman
+# Andreas Franke <afranke@mathweb.org>
+# Stephen Lee <slee@uk.bnsmc.com>
+# Marc Schumann <wurblzap@gmail.com>
+
+package Bugzilla::Search::Quicksearch;
+
+# Make it harder for us to do dangerous things in Perl.
+use strict;
+
+use Bugzilla;
+use Bugzilla::Config;
+use Bugzilla::Error;
+
+use base qw(Exporter);
+@Bugzilla::Search::Quicksearch::EXPORT = qw(quicksearch);
+
+my $cgi = Bugzilla->cgi;
+
+# Word renamings
+my %mappings = (# Status, Resolution, Platform, OS, Priority, Severity
+ "status" => "bug_status",
+ "resolution" => "resolution", # no change
+ "platform" => "rep_platform",
+ "os" => "op_sys",
+ "opsys" => "op_sys",
+ "priority" => "priority", # no change
+ "pri" => "priority",
+ "severity" => "bug_severity",
+ "sev" => "bug_severity",
+ # People: AssignedTo, Reporter, QA Contact, CC, Added comment (?)
+ "owner" => "assigned_to", # deprecated since bug 76507
+ "assignee" => "assigned_to",
+ "assignedto" => "assigned_to",
+ "reporter" => "reporter", # no change
+ "rep" => "reporter",
+ "qa" => "qa_contact",
+ "qacontact" => "qa_contact",
+ "cc" => "cc", # no change
+ # Product, Version, Component, Target Milestone
+ "product" => "product", # no change
+ "prod" => "product",
+ "version" => "version", # no change
+ "ver" => "version",
+ "component" => "component", # no change
+ "comp" => "component",
+ "milestone" => "target_milestone",
+ "target" => "target_milestone",
+ "targetmilestone" => "target_milestone",
+ # Summary, Description, URL, Status whiteboard, Keywords
+ "summary" => "short_desc",
+ "shortdesc" => "short_desc",
+ "desc" => "longdesc",
+ "description" => "longdesc",
+ #"comment" => "longdesc", # ???
+ # reserve "comment" for "added comment" email search?
+ "longdesc" => "longdesc",
+ "url" => "bug_file_loc",
+ "whiteboard" => "status_whiteboard",
+ "statuswhiteboard" => "status_whiteboard",
+ "sw" => "status_whiteboard",
+ "keywords" => "keywords", # no change
+ "kw" => "keywords",
+ # Attachments
+ "attachment" => "attachments.description",
+ "attachmentdesc" => "attachments.description",
+ "attachdesc" => "attachments.description",
+ "attachmentdata" => "attachments.thedata",
+ "attachdata" => "attachments.thedata",
+ "attachmentmimetype" => "attachments.mimetype",
+ "attachmimetype" => "attachments.mimetype");
+
+# We might want to put this into localconfig or somewhere
+my @platforms = ('pc', 'sun', 'macintosh', 'mac');
+my @productExceptions = ('row' # [Browser]
+ # ^^^
+ ,'new' # [MailNews]
+ # ^^^
+ );
+my @componentExceptions = ('hang' # [Bugzilla: Component/Keyword Changes]
+ # ^^^^
+ );
+
+# Quicksearch-wide globals for boolean charts.
+my $chart = 0;
+my $and = 0;
+my $or = 0;
+
+sub quicksearch {
+ my ($searchstring) = (@_);
+
+ # Remove leading and trailing commas and whitespace.
+ $searchstring =~ s/(^[\s,]+|[\s,]+$)//g;
+ ThrowUserError('buglist_parameters_required') unless ($searchstring);
+
+ if ($searchstring =~ m/^[0-9,\s]*$/) {
+ # Bug number(s) only.
+
+ # Allow separation by comma or whitespace.
+ $searchstring =~ s/[,\s]+/,/g;
+
+ if (index($searchstring, ',') < $[) {
+ # Single bug number; shortcut to show_bug.cgi.
+ print $cgi->redirect(-uri => Param('urlbase') .
+ "show_bug.cgi?id=$searchstring");
+ exit;
+ }
+ else {
+ # List of bug numbers.
+ $cgi->param('bug_id', $searchstring);
+ $cgi->param('order', 'bugs.bug_id');
+ $cgi->param('bugidtype', 'include');
+ }
+ }
+ else {
+ # It's not just a bug number or a list of bug numbers.
+ # Maybe it's an alias?
+ if ($searchstring =~ /^([^,\s]+)$/) {
+ if (Bugzilla->dbh->selectrow_array(q{SELECT COUNT(*)
+ FROM bugs
+ WHERE alias = ?},
+ undef,
+ $1)) {
+ print $cgi->redirect(-uri => Param('urlbase') .
+ "show_bug.cgi?id=$1");
+ exit;
+ }
+ }
+
+ # It's no alias either, so it's a more complex query.
+
+ &::GetVersionTable();
+
+ # Globally translate " AND ", " OR ", " NOT " to space, pipe, dash.
+ $searchstring =~ s/\s+AND\s+/ /g;
+ $searchstring =~ s/\s+OR\s+/|/g;
+ $searchstring =~ s/\s+NOT\s+/ -/g;
+
+ my @words = splitString($searchstring);
+ my $searchComments = $#words < Param('quicksearch_comment_cutoff');
+ my @openStates = &::OpenStates();
+ my @closedStates;
+ my (%states, %resolutions);
+
+ foreach (@::legal_bug_status) {
+ push(@closedStates, $_) unless &::IsOpenedState($_);
+ }
+ foreach (@openStates) { $states{$_} = 1 }
+ if ($words[0] eq 'ALL') {
+ foreach (@::legal_bug_status) { $states{$_} = 1 }
+ shift @words;
+ }
+ elsif ($words[0] eq 'OPEN') {
+ shift @words;
+ }
+ elsif ($words[0] =~ /^\+[A-Z]+(,[A-Z]+)*$/) {
+ # e.g. +DUP,FIX
+ if (matchPrefixes(\%states,
+ \%resolutions,
+ [split(/,/, substr($words[0], 1))],
+ \@closedStates,
+ \@::legal_resolution)) {
+ shift @words;
+ # Allowing additional resolutions means we need to keep
+ # the "no resolution" resolution.
+ $resolutions{'---'} = 1;
+ }
+ else {
+ # Carry on if no match found.
+ }
+ }
+ elsif ($words[0] =~ /^[A-Z]+(,[A-Z]+)*$/) {
+ # e.g. NEW,ASSI,REOP,FIX
+ undef %states;
+ if (matchPrefixes(\%states,
+ \%resolutions,
+ [split(/,/, $words[0])],
+ \@::legal_bug_status,
+ \@::legal_resolution)) {
+ shift @words;
+ }
+ else {
+ # Carry on if no match found
+ foreach (@openStates) { $states{$_} = 1 }
+ }
+ }
+ else {
+ # Default: search for unresolved bugs only.
+ # Put custom code here if you would like to change this behaviour.
+ }
+
+ # If we have wanted resolutions, allow closed states
+ if (keys(%resolutions)) {
+ foreach (@closedStates) { $states{$_} = 1 }
+ }
+
+ $cgi->param('bug_status', keys(%states));
+ $cgi->param('resolution', keys(%resolutions));
+
+ # Loop over all main-level QuickSearch words.
+ foreach my $qsword (@words) {
+ my $negate = substr($qsword, 0, 1) eq '-';
+ if ($negate) {
+ $qsword = substr($qsword, 1);
+ }
+
+ my $firstChar = substr($qsword, 0, 1);
+ my $baseWord = substr($qsword, 1);
+ my @subWords = split(/[\|,]/, $baseWord);
+ if ($firstChar eq '+') {
+ foreach (@subWords) {
+ addChart('short_desc', 'substring', $qsword, $negate);
+ }
+ }
+ elsif ($firstChar eq '#') {
+ addChart('short_desc', 'anywords', $baseWord, $negate);
+ if ($searchComments) {
+ addChart('longdesc', 'anywords', $baseWord, $negate);
+ }
+ }
+ elsif ($firstChar eq ':') {
+ foreach (@subWords) {
+ addChart('product', 'substring', $_, $negate);
+ addChart('component', 'substring', $_, $negate);
+ }
+ }
+ elsif ($firstChar eq '@') {
+ foreach (@subWords) {
+ addChart('assigned_to', 'substring', $_, $negate);
+ }
+ }
+ elsif ($firstChar eq '[') {
+ addChart('short_desc', 'substring', $baseWord, $negate);
+ addChart('status_whiteboard', 'substring', $baseWord, $negate);
+ }
+ elsif ($firstChar eq '!') {
+ addChart('keywords', 'anywords', $baseWord, $negate);
+
+ }
+ else { # No special first char
+
+ # Split by '|' to get all operands for a boolean OR.
+ foreach my $or_operand (split(/\|/, $qsword)) {
+ if ($or_operand =~ /^votes:([0-9]+)$/) {
+ # votes:xx ("at least xx votes")
+ addChart('votes', 'greaterthan', $1, $negate);
+ }
+ elsif ($or_operand =~ /^([^:]+):([^:]+)$/) {
+ # generic field1,field2,field3:value1,value2 notation
+ my @fields = split(/,/, $1);
+ my @values = split(/,/, $2);
+ foreach my $field (@fields) {
+ # Be tolerant about unknown fields
+ next unless defined($mappings{$field});
+ $field = $mappings{$field};
+ foreach (@values) {
+ addChart($field, 'substring', $_, $negate);
+ }
+ }
+
+ }
+ else {
+
+ # Having ruled out the special cases, we may now split
+ # by comma, which is another legal boolean OR indicator.
+ foreach my $word (split(/,/, $or_operand)) {
+ # Platform
+ if (grep({lc($word) eq $_} @platforms)) {
+ addChart('rep_platform', 'substring',
+ $word, $negate);
+ }
+ # Priority
+ elsif ($word =~ m/^[pP]([1-5](-[1-5])?)$/) {
+ addChart('priority', 'regexp',
+ "[$1]", $negate);
+ }
+ # Severity
+ elsif (grep({lc($word) eq substr($_, 0, 3)}
+ @::legal_severity)) {
+ addChart('bug_severity', 'substring',
+ $word, $negate);
+ }
+ # Votes (votes>xx)
+ elsif ($word =~ m/^votes>([0-9]+)$/) {
+ addChart('votes', 'greaterthan',
+ $1, $negate);
+ }
+ # Votes (votes>=xx, votes=>xx)
+ elsif ($word =~ m/^votes(>=|=>)([0-9]+)$/) {
+ addChart('votes', 'greaterthan',
+ $2-1, $negate);
+
+ }
+ else { # Default QuickSearch word
+
+ if (!grep({lc($word) eq $_}
+ @productExceptions) &&
+ length($word)>2
+ ) {
+ addChart('product', 'substring',
+ $word, $negate);
+ }
+ if (!grep({lc($word) eq $_}
+ @componentExceptions) &&
+ length($word)>2
+ ) {
+ addChart('component', 'substring',
+ $word, $negate);
+ }
+ if (grep({lc($word) eq $_}
+ @::legal_keywords)) {
+ addChart('keywords', 'substring',
+ $word, $negate);
+ if (length($word)>2) {
+ addChart('short_desc', 'substring',
+ $word, $negate);
+ addChart('status_whiteboard',
+ 'substring',
+ $word, $negate);
+ }
+
+ }
+ else {
+
+ addChart('short_desc', 'substring',
+ $word, $negate);
+ addChart('status_whiteboard', 'substring',
+ $word, $negate);
+ }
+ if ($searchComments) {
+ addChart('longdesc', 'substring',
+ $word, $negate);
+ }
+ }
+ # URL field (for IP addrs, host.names,
+ # scheme://urls)
+ if ($word =~ m/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/
+ || $word =~ /^[A-Za-z]+(\.[A-Za-z]+)+/
+ || $word =~ /:[\\\/][\\\/]/
+ || $word =~ /localhost/
+ || $word =~ /mailto[:]?/
+ # || $word =~ /[A-Za-z]+[:][0-9]+/ #host:port
+ ) {
+ addChart('bug_file_loc', 'substring',
+ $word, $negate);
+ }
+ } # foreach my $word (split(/,/, $qsword))
+ } # votes and generic field detection
+ } # foreach (split(/\|/, $_))
+ } # "switch" $firstChar
+ $chart++;
+ $and = 0;
+ $or = 0;
+ } # foreach (@words)
+
+ # We've been very tolerant about invalid queries, so all that's left
+ # may be an empty query.
+ scalar($cgi->param())>0 || ThrowUserError("buglist_parameters_required");
+ }
+
+ # List of quicksearch-specific CGI parameters to get rid of.
+ my @params_to_strip = ('quicksearch', 'load', 'run');
+ my $modified_query_string = $cgi->canonicalise_query(@params_to_strip);
+
+ if ($cgi->param('load')) {
+ # Param 'load' asks us to display the query in the advanced search form.
+ print $cgi->redirect(-uri => Param('urlbase') . "query.cgi?" .
+ "format=advanced&amp;" .
+ $modified_query_string);
+ }
+
+ # Otherwise, pass the modified query string to the caller.
+ # We modified $cgi->params, so the caller can choose to look at that, too,
+ # and disregard the return value.
+ $cgi->delete(@params_to_strip);
+ return $modified_query_string;
+}
+
+###########################################################################
+# Helpers
+###########################################################################
+
+# Split string on whitespace, retaining quoted strings as one
+sub splitString {
+ my $string = shift;
+ my @quoteparts;
+ my @parts;
+ my $i = 0;
+
+ # Escape backslashes
+ $string =~ s/\\/\\\//g;
+
+ # Now split on quote sign; be tolerant about unclosed quotes
+ @quoteparts = split(/"/, $string);
+ foreach (@quoteparts) {
+ # After every odd quote, escape whitespace
+ s/(\s)/\\$1/g if $i++ % 2;
+ }
+ # Join again
+ $string = join('"', @quoteparts);
+
+ # Now split on unescaped whitespace
+ @parts = split(/(?<!\\)\s+/, $string);
+ foreach (@parts) {
+ # Restore whitespace
+ s/\\(\s)/$1/g;
+ # Restore backslashes
+ s/\\\//\\/g;
+ # Remove quotes
+ s/"//g;
+ }
+ return @parts;
+}
+
+# Expand found prefixes to states or resolutions
+sub matchPrefixes {
+ my $hr_states = shift;
+ my $hr_resolutions = shift;
+ my $ar_prefixes = shift;
+ my $ar_check_states = shift;
+ my $ar_check_resolutions = shift;
+ my $foundMatch = 0;
+
+ foreach my $prefix (@$ar_prefixes) {
+ foreach (@$ar_check_states) {
+ if (/^$prefix/) {
+ $$hr_states{$_} = 1;
+ $foundMatch = 1;
+ }
+ }
+ foreach (@$ar_check_resolutions) {
+ if (/^$prefix/) {
+ $$hr_resolutions{$_} = 1;
+ $foundMatch = 1;
+ }
+ }
+ }
+ return $foundMatch;
+}
+
+# Negate comparison type
+sub negateComparisonType {
+ my $comparisonType = shift;
+
+ if ($comparisonType eq 'substring') {
+ return 'notsubstring';
+ }
+ elsif ($comparisonType eq 'anywords') {
+ return 'nowords';
+ }
+ elsif ($comparisonType eq 'regexp') {
+ return 'notregexp';
+ }
+ else {
+ # Don't know how to negate that
+ ThrowCodeError('unknown_comparison_type');
+ }
+}
+
+# Add a boolean chart
+sub addChart {
+ my ($field, $comparisonType, $value, $negate) = @_;
+
+ $negate && ($comparisonType = negateComparisonType($comparisonType));
+ makeChart("$chart-$and-$or", $field, $comparisonType, $value);
+ if ($negate) {
+ $and++;
+ $or = 0;
+ }
+ else {
+ $or++;
+ }
+}
+
+# Create the CGI parameters for a boolean chart
+sub makeChart {
+ my ($expr, $field, $type, $value) = @_;
+
+ $cgi->param("field$expr", $field);
+ $cgi->param("type$expr", $type);
+ $cgi->param("value$expr", $value);
+}
+
+1;
diff --git a/QUICKSTART b/QUICKSTART
index 3f26f06d1..54ebfa4cf 100644
--- a/QUICKSTART
+++ b/QUICKSTART
@@ -30,10 +30,6 @@ of the Bugzilla Guide in the docs/ directory.
If you want to change platforms, operating systems, severities and
priorities, this can also be done in localconfig at this time.
- You should also update localconfig.js to reflect these changes. This
- includes setting the URL you chose in step 1 as the 'bugzilla' JS
- variable.
-
5. Using the name you provided as $db_name above, create a MySQL database
for Bugzilla. You should also create a user permission for the name
supplied as $db_user with read/write access to that database.
diff --git a/buglist.cgi b/buglist.cgi
index 904df703d..63ab55951 100755
--- a/buglist.cgi
+++ b/buglist.cgi
@@ -38,6 +38,7 @@ use vars qw($template $vars);
use Bugzilla;
use Bugzilla::Search;
+use Bugzilla::Search::Quicksearch;
use Bugzilla::Constants;
use Bugzilla::User;
@@ -65,6 +66,15 @@ if (length($buffer) == 0) {
ThrowUserError("buglist_parameters_required");
}
+# Determine whether this is a quicksearch query.
+my $searchstring = $cgi->param('quicksearch');
+if (defined($searchstring)) {
+ $buffer = quicksearch($searchstring);
+ # Quicksearch may do a redirect, in which case it does not return.
+ # If it does return, it has modified $cgi->params so we can use them here
+ # as if this had been a normal query from the beginning.
+}
+
################################################################################
# Data and Security Validation
################################################################################
diff --git a/checksetup.pl b/checksetup.pl
index f20d1dcb2..b2bb97162 100755
--- a/checksetup.pl
+++ b/checksetup.pl
@@ -1015,9 +1015,6 @@ if ($my_create_htaccess) {
<FilesMatch ^(.*\.pl|.*localconfig.*)$>
deny from all
</FilesMatch>
-<FilesMatch ^(localconfig.js|localconfig.rdf)$>
- allow from all
-</FilesMatch>
END
close HTACCESS;
chmod $fileperm, ".htaccess";
@@ -1033,11 +1030,6 @@ END
print "Repairing .htaccess...\n";
open HTACCESS, '>', '.htaccess';
print HTACCESS $oldaccess;
- print HTACCESS <<'END';
-<FilesMatch ^(localconfig.js|localconfig.rdf)$>
- allow from all
-</FilesMatch>
-END
close HTACCESS;
}
diff --git a/defparams.pl b/defparams.pl
index 598d0711f..ffb9c68d9 100644
--- a/defparams.pl
+++ b/defparams.pl
@@ -1424,6 +1424,17 @@ Reason: %reason%
default => 1,
},
+ {
+ name => 'quicksearch_comment_cutoff',
+ desc => q{The maximum number of search terms for a QuickSearch to search
+ comments.
+ If the QuickSearch query contains more terms than this value,
+ QuickSearch will not search comments.},
+ type => 't',
+ default => '4',
+ checker => \&check_numeric
+ },
+
# Added for Patch Viewer stuff (attachment.cgi?action=diff)
{
name => 'cvsroot',
diff --git a/docs/xml/security.xml b/docs/xml/security.xml
index a638ae26a..e68577b4c 100644
--- a/docs/xml/security.xml
+++ b/docs/xml/security.xml
@@ -1,5 +1,5 @@
<!-- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"> -->
-<!-- $Id: security.xml,v 1.6 2005/06/29 23:43:33 zach%zachlipton.com Exp $ -->
+<!-- $Id: security.xml,v 1.7 2005/08/21 18:16:41 lpsolit%gmail.com Exp $ -->
<chapter id="security">
<title>Bugzilla Security</title>
@@ -207,14 +207,6 @@ skip-networking
</simplelist>
</para>
</listitem>
- <listitem>
- <para>But allow:
- <simplelist type="inline">
- <member><filename>localconfig.js</filename></member>
- <member><filename>localconfig.rdf</filename></member>
- </simplelist>
- </para>
- </listitem>
</itemizedlist>
</listitem>
diff --git a/docs/xml/using.xml b/docs/xml/using.xml
index 720f461e9..5a11730cc 100644
--- a/docs/xml/using.xml
+++ b/docs/xml/using.xml
@@ -725,11 +725,12 @@
summary and status whiteboard of a bug; adding
"<filename>:BazProduct</filename>" would
search only in that product.
+ You can use it to find a bug by its number or its alias, too.
</para>
- <para>You'll find the Quicksearch box on Bugzilla's
- front page, along with a
- <ulink url="../../quicksearch.html">Help</ulink>
+ <para>You'll find the Quicksearch box in Bugzilla's footer area.
+ On Bugzilla's front page, there is an additional
+ <ulink url="../../page.cgi?id=quicksearch.html">Help</ulink>
link which details how to use it.</para>
</section>
diff --git a/localconfig.js b/localconfig.js
deleted file mode 100644
index 2cbe6f24f..000000000
--- a/localconfig.js
+++ /dev/null
@@ -1,75 +0,0 @@
-//
-// This file contains the installation specific values for QuickSearch.
-// See quicksearch.js for more details.
-//
-
-// the global bugzilla url
-
-var bugzilla = "";
-//var bugzilla = "http://bugzilla.mozilla.org/";
-
-// Status and Resolution
-// ---------------------
-
-var statuses_open = new Array("UNCONFIRMED","NEW","ASSIGNED","REOPENED");
-var statuses_resolved = new Array("RESOLVED","VERIFIED","CLOSED");
-var resolutions = new Array("FIXED","INVALID","WONTFIX","LATER",
- "REMIND","DUPLICATE","WORKSFORME","MOVED");
-
-// Keywords
-// --------
-//
-// Enumerate all your keywords here. This is necessary to avoid
-// "foo is not a legal keyword" errors. This makes it possible
-// to include the keywords field in the search by default.
-
-var keywords = new Array(
-// "foo", "bar", "baz"
-);
-
-// Platforms
-// ---------
-//
-// A list of words <w> (substrings of platform values)
-// that will automatically be translated to "platform:<w>"
-// E.g. if "mac" is defined as a platform, then searching
-// for it will find all bugs with platform="Macintosh",
-// but no other bugs with e.g. "mac" in the summary.
-
-var platforms = new Array(
-"pc","sun","macintosh","mac" //shortcut added
-//,"dec","hp","sgi"
-//,"all" //this is a legal value for OpSys, too :(
-//,"other"
-);
-
-// Severities
-// ----------
-//
-// A list of words <w> (substrings of severity values)
-// that will automatically be translated to "severity:<w>"
-// E.g with this default set of severities, searching for
-// "blo,cri,maj" will find all severe bugs.
-
-var severities = new Array("blo","cri","maj","nor","min","tri","enh");
-
-// Products and Components
-// -----------------------
-//
-// It is not necessary to list all products and components here.
-// Instead, you can define a "blacklist" for some commonly used
-// words or word fragments that occur in a product or component name
-// but should _not_ trigger product/component search.
-
-var product_exceptions = new Array(
-"row" // [Browser]
- // ^^^
-,"new" // [MailNews]
- // ^^^
-);
-
-var component_exceptions = new Array(
-"hang" // [mozilla.org] Bugzilla: Component/Keyword Changes
- // ^^^^
-);
-
diff --git a/quicksearch.html b/quicksearch.html
deleted file mode 100644
index 1b1ecb1a6..000000000
--- a/quicksearch.html
+++ /dev/null
@@ -1,151 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <title>Bugzilla QuickSearch</title>
-</head>
-
-<body bgcolor="#ffffff">
-
-<p>
-<small>If you are already familiar with the original
-<a href="query.cgi">Bugzilla Query Form</a>,
-you may prefer <a href="quicksearchhack.html">this form</a>.
-</small>
-</p>
-
-<script src="localconfig.js" type="text/javascript"></script>
-<script src="quicksearch.js" type="text/javascript"></script>
-
-<h1>Bugzilla QuickSearch</h1>
-
-<p>
-Type in one or more words (or word fragments) to search for:
-</p>
-
-<form name="f" action="show_bug.cgi" method="get"
- onsubmit="QuickSearch(f.id.value); return false;">
- <table>
- <tr>
- <td><input type="text" size="40" name="id"></td>
- <td align="left"><input type="submit" value="Search"></td>
- <!-- <td><a href="javascript:QuickSearch_Help();">[Help]</a></td> -->
- </tr>
- </table>
-</form>
-
-<script type="text/javascript">
-<!--
-document.forms['f'].id.focus();
-//-->
-</script>
-
-<h2>Getting Started</h2>
-
-<ul>
-<li> This is <b>case-insensitive</b> search.
- <ul>
- <li> &nbsp;<tt>table</tt>&nbsp;, &nbsp;<tt>Table</tt>&nbsp;
- and &nbsp;<tt>TABLE</tt>&nbsp; are all the same.</li>
- </ul>
-</li>
-<li> This is <b>all words as substrings</b> search.<br>
- Therefore you should <b>use stems</b> to get better results:
- <ul>
- <li> Use <tt>localiz</tt> instead of <tt>localize</tt> or
- <tt>localization</tt>.</li>
- <li> Use <tt>bookmark</tt> instead of <tt>bookmarks</tt> or
- <tt>bookmarking</tt>.</li>
- </ul>
-</li>
-</ul>
-
-<h2><a name="features">Features</a></h2>
-
-<ul>
-<li> Boolean operations: ``<tt>-foo</tt>''(NOT), ``<tt>foo bar</tt>''(AND),
- ``<tt>foo|bar</tt>''(OR).
- <ul>
- <li> <b>NOT</b>: Use &nbsp;<tt><b>-</b><i>foo</i></tt>&nbsp; to exclude bugs
- with &nbsp;<tt><i>foo</i></tt>&nbsp; in the summary.</li>
- <li> <b>AND</b>: Space-separated words are treated as a conjunction.</li>
- <li> <b>OR</b>: Within a word, "|"-separated parts denote alternatives. </li>
- <li> Besides "|", a comma can be used to separate alternatives.</li>
- <li> OR has higher precedence than AND; AND is the top level operation</li>
- </ul>
- <i>Example:</i> &nbsp;<tt>url,location bar,field -focus</tt>&nbsp;
- means
- (<tt>url</tt> OR <tt>location</tt>) AND (<tt>bar</tt> OR <tt>field</tt>) AND (NOT <tt>focus</tt>)
-<p>
-</li>
-<li>Use &nbsp;<tt>+foo</tt>&nbsp; to search for bugs where the <b>summary</b> contains &nbsp;<tt>foo</tt>&nbsp; as a <b>substring</b>.<br>
- Use &nbsp;<tt>#foo</tt>&nbsp; to search for bugs where the <b>summary</b> contains the <b>word</b> &nbsp;<tt>foo</tt>&nbsp;
- <ul>
- <li> &nbsp;<tt>+brow</tt>&nbsp; does not find all bugs in the &nbsp;<tt>Browser</tt>&nbsp; product</li>
- <li> &nbsp;<tt>#title</tt>&nbsp; does not find bugs bugs with &nbsp;<tt>titlebar</tt>&nbsp; or &nbsp;<tt>titled</tt>&nbsp;</li>
- </ul>
- Phrases with special chars (space, comma, +, -, #, ...) can be <b>quoted</b>:
- <ul>
- <li> &nbsp;<tt>"lock icon"</tt>&nbsp;</li>
- </ul>
-<p>
-</li>
-<li> <b>Open vs. Resolved Bugs</b>:<br>
- By default, only open (i.e. unresolved) bugs are shown.
- Use &nbsp;<tt>+DUP</tt>&nbsp; as first word in your query
- to include duplicate bugs in your search,
- &nbsp;<tt>FIXED</tt>&nbsp; to search for fixed bugs only,
- or &nbsp;<tt>ALL</tt>&nbsp; to search all bugs,
- regardless of status or resolution. Searching for duplicates is
- recommended if you can't find an open bug directly.
- <ul>
- <li> &nbsp;<tt>+DUP,FIXED table border</tt>&nbsp;</li>
- <li> &nbsp;<tt>ALL mouse wheel</tt>&nbsp;</li>
- </ul>
-<p></li>
-<li> <b>Focus the Search with Products &amp; Components</b>:<br>
- To search for bugs in product "Foo Bar" only, add
- &nbsp;<tt>:foo</tt>&nbsp; or &nbsp;<tt>:bar</tt>&nbsp; or both
- to your query.
- You can do this with any substring of a
- <a href="describecomponents.cgi">product or component</a>
- to focus the search.
-</li>
-</ul>
-
-<h2>More Tips</h2>
-
-<ul>
-<li> You can also use this tool to <b>lookup</b> a bug by its number.
- <ul>
- <li> &nbsp;<tt>12345</tt>&nbsp;</li>
- </ul>
-</li>
-<li> A comma-separated list of bug numbers gives you a list of these bugs.
- <ul>
- <li> &nbsp;<tt>12345,23456,34567</tt>&nbsp;</li>
- </ul>
-</li>
-</ul>
-
-<p>
-By default, the following fields are searched: Summary, Keywords, Product,
-Component, Status Whiteboard. If a word looks like a part of a URL, that field
-is included in the search, too.
-</p>
-<!--
-<small>For further details, see
-<a href="http://bugzilla.mozilla.org/show_bug.cgi?id=61561">Bug 61561</a> and
-<a href="http://bugzilla.mozilla.org/show_bug.cgi?id=69793">Bug 69793</a>.
-</small>
- -->
-<hr>
-
-<p>
-Use the powerful
-<a href="query.cgi">Bugzilla Query Form</a>
-for advanced queries.
-</p>
-
-</body>
-</html>
diff --git a/quicksearch.js b/quicksearch.js
deleted file mode 100644
index 29ab6eb6b..000000000
--- a/quicksearch.js
+++ /dev/null
@@ -1,740 +0,0 @@
-//
-// This is the main JS file for QuickSearch.
-//
-// Derived from:
-//
-// * C. Begle's SimpleSearch tool:
-// http://www.mozilla.org/quality/help/simplesearch.html
-// http://www.mozilla.org/quality/help/bugreport.js
-//
-// * Jesse Ruderman's bugzilla search page:
-// http://www.cs.hmc.edu/~jruderma/s/bugz.html
-//
-// Created by
-// Andreas Franke <afranke@mathweb.org>
-//
-// Contributors:
-// Stephen Lee <slee@uk.bnsmc.com>
-
-
-// Use no_result variable to avoid problems with "undefined" on some browsers
-
-var no_result="---";
-
-// do_unshift(l, s) is equivalent to l.unshift(s), but some browsers do not
-// support the built-in function.
-
-function do_unshift(l, s) {
- l.length = l.length + 1;
- for (var i=l.length-1; i>0; i--) {
- l[i] = l[i-1];
- }
- l[0] = s;
- return l.length;
-}
-
-// do_shift(l) is equivalent to l.shift(s), but some browsers do not
-// support the built-in function.
-
-function do_shift(l) {
- var l0=l[0];
- for (var i=0; i<l.length-1; i++) {
- l[i] = l[i+1];
- }
- l.length = l.length - 1;
- return l0;
-}
-
-function go_to (url) {
- // XXX specifying "sidebar" here indicates you want to use a
- // function to do the actual loading instead of using the specified
- // url directly. bug 236025 covers clarifying this. Pages that specify
- // sidebar=1 *must* specify a load_absolute_url function meanwhile.
- if ( typeof sidebar != "undefined" && sidebar == 1 ) {
- load_absolute_url(url);
- } else {
- document.location.href = url;
- }
-}
-
-function map(l, f) {
- var l1 = new Array();
- for (var i=0; i<l.length; i++) {
- l1[i] = f(l[i]);
- }
- return l1;
-}
-
-function isPrefix(s1, s2) {
- return (s1.length <= s2.length) &&
- (s1 == s2.substring(0,s1.length))
-}
-
-function member(s, l) {
- for (var i=0; i<l.length; i++) {
- if (l[i] == s) return true;
- }
- return false;
-}
-
-function add(s, l) {
- if (! member(s, l)) {
- do_unshift(l,s);
- }
-}
-
-function addAll(l1, l2) {
- for (var i=0; i<l1.length; i++) {
- add(l1[i],l2);
- }
-}
-
-function isSubset (l1, l2) {
- return (l1.length == 0)
- || (member(l1[0],l2) && subset(l1.slice(1),l2));
-}
-
-// fields
-
-var f1 = new Array();
-var f2 = new Array();
-
-function add_mapping(from,to) {
- f1[f1.length] = from;
- f2[f2.length] = to;
-}
-
-// Status, Resolution, Platform, OS, Priority, Severity
-add_mapping("status", "bug_status");
-add_mapping("resolution", "resolution"); // no change
-add_mapping("platform", "rep_platform");
-add_mapping("os", "op_sys");
-add_mapping("opsys", "op_sys");
-add_mapping("priority", "priority"); // no change
-add_mapping("pri", "priority");
-add_mapping("severity", "bug_severity");
-add_mapping("sev", "bug_severity");
-// People: AssignedTo, Reporter, QA Contact, CC, Added comment (?)
-add_mapping("owner", "assigned_to");
-add_mapping("assignee", "assigned_to");
-add_mapping("assignedto", "assigned_to");
-add_mapping("reporter", "reporter"); // no change
-add_mapping("rep", "reporter");
-add_mapping("qa", "qa_contact");
-add_mapping("qacontact", "qa_contact");
-add_mapping("cc", "cc"); // no change
-// Product, Version, Component, Target Milestone
-add_mapping("product", "product"); // no change
-add_mapping("prod", "product");
-add_mapping("version", "version"); // no change
-add_mapping("ver", "version");
-add_mapping("component", "component"); // no change
-add_mapping("comp", "component");
-add_mapping("milestone", "target_milestone");
-add_mapping("target", "target_milestone");
-add_mapping("targetmilestone", "target_milestone");
-// Summary, Description, URL, Status whiteboard, Keywords
-add_mapping("summary", "short_desc");
-add_mapping("shortdesc", "short_desc");
-add_mapping("desc", "longdesc");
-add_mapping("description", "longdesc");
-//add_mapping("comment", "longdesc"); // ???
- // reserve "comment" for "added comment" email search?
-add_mapping("longdesc", "longdesc");
-add_mapping("url", "bug_file_loc");
-add_mapping("whiteboard", "status_whiteboard");
-add_mapping("statuswhiteboard", "status_whiteboard");
-add_mapping("sw", "status_whiteboard");
-add_mapping("keywords", "keywords"); // no change
-add_mapping("kw", "keywords");
-// Attachments
-add_mapping("attachment", "attachments.description");
-add_mapping("attachmentdesc", "attachments.description");
-add_mapping("attachdesc", "attachments.description");
-add_mapping("attachmentdata", "attachments.thedata");
-add_mapping("attachdata", "attachments.thedata");
-add_mapping("attachmentmimetype", "attachments.mimetype");
-add_mapping("attachmimetype", "attachments.mimetype");
-
-// disabled because of bug 30823:
-// "BugsThisDependsOn" --> "dependson"
-// "OtherBugsDependingOnThis"--> "blocked"
-//add_mapping("dependson", "dependson");
-//add_mapping("blocked", "blocked");
-
-// Substring search doesn't make much sense for the following fields:
-// "Attachment is patch" --> "attachments.ispatch"
-// "Last changed date" --> "delta_ts"
-// "Days since bug changed" --> "(to_days(now()) - to_days(bugs.delta_ts))"
-//"groupset"
-//"everconfirmed"
-//"bug","bugid","bugno" --> "bug_id"
-// "votes" --> "votes"
-// "votes>5", "votes>=5", "votes=>5" works now, see below
-// "votes:5" is interpreted as "votes>=5"
-
-function findIndex(array,value) {
- for (var i=0; i<array.length; i++)
- if (array[i] == value) return i;
- return -1;
-}
-
-function mapField(fieldname) {
- var i = findIndex(f1,fieldname);
- if (i >= 0) return f2[i];
- return no_result;
-}
-
-// `keywords' is defined externally
-
-function is_keyword(s) {
- return member(s, keywords);
-}
-
-// `platforms' is defined externally
-
-function is_platform(str) {
- return member (str.toLowerCase(),platforms);
-}
-
-// `severities' is defined externally
-
-function is_severity(str) {
- return member(str.toLowerCase(),severities);
-}
-
-// `product_exceptions' is defined externally
-
-function match_product(str) {
- var s = str.toLowerCase();
- return (s.length > 2) && (! member(s,product_exceptions));
-}
-
-// `component_exceptions are defined externally
-
-function match_component(str) {
- var s = str.toLowerCase();
- return (s.length > 2) && (! member(s,component_exceptions));
-}
-
-var status_and_resolution = ""; // for pretty debug output only; these vars
-var charts = ""; // always hold the data from the last query
-
-// derived from http://www.mozilla.org/quality/help/bugreport.js
-
-function make_chart(expr, field, type, value) {
- charts += "<tr>" +
- "<td><tt>" + expr + "</tt></td>" +
- "<td><tt>" + field + "</tt></td>" +
- "<td><tt>" + type + "</tt></td>" +
- "<td><tt>" + value + "</tt></td>" +
- "</tr>";
- return "&field" + expr + "=" + field +
- "&type" + expr + "=" + type +
- "&value" + expr + "=" + escape(value).replace(/[+]/g,"%2B");
-}
-
-// returns true if at least one of comparelist had the prefix, false otherwise
-function addPrefixMatches(prefix, comparelist, resultlist) {
- var foundMatch = false;
- for (var i=0; i<comparelist.length; i++) {
- if (isPrefix(prefix,comparelist[i])) {
- foundMatch = true;
- add(comparelist[i],resultlist);
- }
- }
- return foundMatch;
-}
-
-function prefixesNotFoundError(prefixes,statusValues,resolutionValues) {
- var txt;
- if (prefixes.length == 1) {
- txt = "is not a prefix ";
- } else {
- txt = "are not prefixes ";
- }
- alert(prefixes + "\n" + txt +
- "of one of these status or resolution values:\n" +
- statusValues + "\n" + resolutionValues + "\n");
-}
-
-function make_query_URL(url, input, searchLong) {
-
- status_and_resolution = "";
- charts = "";
-
- // declare all variables used in this function
-
- var searchURL = url; // bugzilla + "buglist.cgi" (or "query.cgi")
- var abort = false; // global flag, checked upon return
-
- var i,j,k,l; // index counters used in 'for' loops
- var parts,input2; // escape "quoted" parts of input
-
- var word; // array of words
- // (space-separated parts of input2)
- var alternative; // array of parts of an element of 'word'
- // (separated by '|', sometimes by comma)
- var comma_separated_words; // array of parts of an element of 'alternative'
- var w; // current element of one of these arrays:
- // word, alternative, comma_separated_words
-
- var w0; // first element of 'word'
- var prefixes; // comma-separated parts of w0
- // (prefixes of status/resolution values)
-
- var expr; // used for 'priority' support
- var n,separator; // used for 'votes' support
-
- var colon_separated_parts, fields,values,field;
- // used for generic fields:values notation
-
- var chart,and,or; // counters used in add_chart
- var negation; // boolean flag used in add_chart
-
- // `statuses_open' and `statuses_resolved' are defined externally
- var statusOpen = statuses_open;
- var statusResolved = statuses_resolved;
- var statusAll = statusOpen.concat(statusResolved);
-
- // `resolutions' is defined externally
- var bug_status = statusOpen.slice().reverse(); //reverse is just cosmetic
- var resolution = new Array();
-
- // escape everything between quotes: "foo bar" --> "foo%20bar"
- parts = input.split('"');
- if ((parts.length % 2) != 1) {
- alert('Unterminated quote');
- abort = true;
- return no_result;
- }
- for (i=1; i<parts.length; i+=2) {
- parts[i] = escape(parts[i]);
- }
- input2 = parts.join('"');
-
- // abort if there are still brackets
- if (input2.match(/[(]|[\)]/)) {
- alert('Brackets (...) are not supported.\n' +
- 'Use quotes "..." for values that contain special characters.');
- abort = true;
- return no_result;
- }
-
- // translate " AND "," OR "," NOT " to space,comma,dash
- input2 = input2.replace(/[\s]+AND[\s]+/g," ");
- input2 = input2.replace(/[\s]+OR[\s]+/g,"|");
- input2 = input2.replace(/[\s]+NOT[\s]+/g," -");
-
- // now split into words at space positions
- word = input2.split(/[\s]+/);
-
- // determine bug_status and resolution
- // the first word may contain relevant info
-
- // This function matches the given prefixes against the given statuses and
- // resolutions. Matched statuses are added to bug_status, matched
- // resolutions are added to resolution. Returns true if and only if
- // some matches were found for at least one of the given prefixes.
- function matchPrefixes(prefixes,statuses,resolutions) {
- var failedPrefixes = new Array();
- var foundMatch = false;
- for (var j=0; j<prefixes.length; j++) {
- var ok1 = addPrefixMatches(prefixes[j],statuses,bug_status);
- var ok2 = addPrefixMatches(prefixes[j],resolutions,resolution);
- if ((! ok1) && (! ok2)) {
- add(prefixes[j],failedPrefixes);
- } else {
- foundMatch = true;
- }
- }
- //report an error if some (but not all) prefixes didn't match anything
- if (foundMatch && (failedPrefixes.length > 0)) {
- prefixesNotFoundError(failedPrefixes,statuses,resolutions);
- abort = true;
- }
- return foundMatch;
- }
-
- if (word[0] == "ALL") {
- // special case: search for bugs regardless of status
- addAll(statusResolved,bug_status);
- do_shift(word);
- } else if (word[0] == "OPEN") {
- // special case: search for open bugs only
- do_shift(word);
- } else if (word[0].match("^[+][A-Z]+(,[A-Z]+)*$")) {
- // e.g. +DUP,FIX
- w0 = do_shift(word);
- prefixes = w0.substring(1).split(",");
- if (! matchPrefixes(prefixes,statusResolved,resolutions)) {
- do_unshift(word,w0);
- }
- } else if (word[0].match("^[A-Z]+(,[A-Z]+)*$")) {
- // e.g. NEW,ASSI,REOP,FIX
- bug_status = new Array(); // reset
- w0 = do_shift(word);
- prefixes = w0.split(",");
- if (! matchPrefixes(prefixes,statusAll,resolutions)) {
- do_unshift(word,w0);
- bug_status = statusOpen.reverse(); //reset to default bug_status
- }
- } else {
- // default case:
- // search for unresolved bugs only
- // uncomment this to include duplicate bugs in the search
- // add("DUPLICATE",resolution);
- }
- if (resolution.length > 0) {
- resolution = resolution.reverse();
- do_unshift(resolution,"---");
- addAll(statusResolved,bug_status);
- }
- bug_status = bug_status.reverse();
- bug_status = map(bug_status,escape);
- searchURL += "?bug_status=" + bug_status.join("&bug_status=");
- status_and_resolution += 'Status: <tt>'+bug_status+'</tt>';
-
- if (resolution.length > 0) {
- resolution = map(resolution,escape);
- searchURL += "&resolution=" + resolution.join("&resolution=");
- status_and_resolution += '<br>'+'Resolution: <tt>'+resolution+'</tt>';
- }
-
- // end of bug_status & resolution stuff
-
- chart = 0;
- and = 0;
- or = 0;
-
- negation = false;
-
- function negate_comparison_type(type) {
- switch(type) {
- case "substring": return "notsubstring";
- case "anywords": return "nowords";
- case "regexp": return "notregexp";
- default:
- // e.g. "greaterthan"
- alert("Can't negate comparison type: `" + type + "'");
- abort = true;
- return "dummy";
- }
- }
-
- function add_chart(field,type,value) {
- // undo escaping for value: '"foo%20bar"' --> 'foo bar'
- var parts = value.split('"');
- if ((parts.length % 2) != 1) {
- alert('Internal error: unescaping failure');
- abort = true;
- }
- for (var i=1; i<parts.length; i+=2) {
- parts[i] = unescape(parts[i]);
- }
- var value2 = parts.join('');
-
- // negate type if negation is set
- var type2 = type;
- if (negation) {
- type2 = negate_comparison_type(type2);
- }
- searchURL += make_chart(chart+"-"+and+"-"+or,field,type2,value2);
- or++;
- if (negation) {
- and++;
- or=0;
- }
- }
-
- for (i=0; i<word.length; i++, chart++) {
-
- w = word[i];
-
- negation = false;
- if (w.charAt(0) == "-") {
- negation = true;
- w = w.substring(1);
- }
-
- switch (w.charAt(0)) {
- case "+":
- alternative = w.substring(1).split(/[|,]/);
- for (j=0; j<alternative.length; j++)
- add_chart("short_desc","substring",alternative[j]);
- break;
- case "#":
- alternative = w.substring(1).replace(/[|,]/g," ");
- add_chart("short_desc","anywords",alternative);
- if (searchLong)
- add_chart("longdesc","anywords",alternative);
- break;
- case ":":
- alternative = w.substring(1).split(",");
- for (j=0; j<alternative.length; j++) {
- add_chart("product","substring",alternative[j]);
- add_chart("component","substring",alternative[j]);
- }
- break;
- case "@":
- alternative = w.substring(1).split(",");
- for (j=0; j<alternative.length; j++)
- add_chart("assigned_to","substring",alternative[j]);
- break;
- case "[":
- add_chart("short_desc","substring",w);
- add_chart("status_whiteboard","substring",w);
- break;
- case "!":
- add_chart("keywords","anywords",w.substring(1));
- break;
- default:
- alternative=w.split("|");
- for (j=0; j<alternative.length; j++) {
-
- w=alternative[j];
-
- // votes:xx ("at least xx votes")
- if (w.match("^votes[:][0-9]+$")) {
- n = w.split(/[:]/)[1];
- add_chart("votes","greaterthan",String(n-1));
- continue;
- }
- // generic field1,field2,field3:value1,value2 notation
- if (w.match("^[^:]+[:][^:\/][^:]*$")) {
- colon_separated_parts = w.split(":");
- fields = colon_separated_parts[0].split(/[,]+/);
- values = colon_separated_parts[1].split(/[,]+/);
- for (k=0; k<fields.length; k++) {
- field = mapField(fields[k]);
- if (field == no_result) {
- alert("`"+fields[k]+"'"+
- " is not a valid field name.");
- abort = true;
- return no_result;
- } else {
- for (l=0; l<values.length; l++) {
- add_chart(field,"substring",values[l]);
- }
- }
- }
- continue;
- }
- comma_separated_words=w.split(/[,]+/);
- for (k=0; k<comma_separated_words.length; k++) {
- w=comma_separated_words[k];
-
- // platform
- if (is_platform(w)) {
- add_chart("rep_platform","substring",w);
- continue;
- }
- // priority
- if (w.match("^[pP][1-5](,[pP]?[1-5])*$")) {
- expr = "["+w.replace(/[p,]/g,"")+"]";
- add_chart("priority","regexp",expr);
- continue;
- }
- if (w.match("^[pP][1-5]-[1-5]$")) {
- expr = "["+w.substring(1)+"]";
- add_chart("priority","regexp",expr);
- continue;
- }
- // severity
- if (is_severity(w)) {
- add_chart("bug_severity","substring",w);
- continue;
- }
- // votes>xx
- if (w.match("^votes>[0-9]+$")) {
- n = w.split(">")[1];
- add_chart("votes","greaterthan",n);
- continue;
- }
- // votes>=xx, votes=>xx
- if (w.match("^votes(>=|=>)[0-9]+$")) {
- separator = w.match("^votes(>=|=>)[0-9]+$")[1];
- n = w.split(separator)[1];
- add_chart("votes","greaterthan",String(n-1));
- continue;
- }
- // really default case
- if (match_product(w)) {
- add_chart("product","substring",w);
- }
- if (match_component(w)) {
- add_chart("component","substring",w);
- }
- if (is_keyword(w)) {
- add_chart("keywords","substring",w);
- if (w.length > 2) {
- add_chart("short_desc","substring",w);
- add_chart("status_whiteboard","substring",w);
- }
- } else {
- add_chart("short_desc","substring",w);
- add_chart("status_whiteboard","substring",w);
- }
- if (searchLong)
- add_chart("longdesc","substring",w);
-
- // URL field (for IP addrs, host.names, scheme://urls)
- if (w.match(/[0-9]+[.][0-9]+[.][0-9]+[.][0-9]+/)
- || w.match(/^[A-Za-z]+([.][A-Za-z]+)+/)
- || w.match(/[:][\/][\/]/)
- || w.match(/localhost/)
- || w.match(/mailto[:]?/)
- // || w.match(/[A-Za-z]+[:][0-9]+/) //host:port
- )
- add_chart("bug_file_loc","substring",w);
- }
- }
- }
- and = 0;
- or = 0;
- }
-
- //searchURL += "&cmdtype=doit";
-
- if (abort == false) {
- return searchURL;
- } else {
- return no_result;
- }
-}
-
-function unique_id () {
- return (new Date()).getTime();
-}
-
-function ShowURL(mode,input) {
- var searchURL = make_query_URL(bugzilla+"buglist.cgi", input, false);
- if (searchURL != no_result) {
- var pieces = searchURL.replace(/[\?]/g,"\n?").replace(/[\&]/g,"\n&");
- if (mode == "alert") {
- alert(pieces);
- } else {
- var table = "<table border=1>" +
- "<thead>" +
- "<tr>" +
- "<th>Chart-And-Or</th>" +
- "<th>Field</th>" +
- "<th>Type</th>" +
- "<th>Value</th>" +
- "</tr>" +
- "</thead>" +
- "<tbody>" + charts + "</tbody>" +
- "</table>";
- var html = '<html>' +
- '<head>' +
- '<title>' + input + '</title>' +
- '</head>' +
- '<body>' +
- '<a href="' + searchURL + '">' +
- 'Submit Query' +
- '</a>' +
- '<p>' + status_and_resolution +
- '<p>' + table +
- '<pre>' +
- pieces.replace(/[\n]/g,"<br>") +
- '</pre>' +
- '</body>' +
- '</html>';
- var w = window.open("","preview_"+unique_id());
- w.document.write(html);
- w.document.close();
- }
- }
-}
-
-//
-// new interface:
-// searchLong is a boolean now (not a checkbox/radiobutton)
-//
-function Search(url, input, searchLong) {
- var inputstring = new String(input);
- var word = inputstring.split(/[\s]+/);
-
- // Check for empty input
- if ( word.length == 1 && word[0] == "" )
- return;
-
- // Check for potential Bugzilla-busting intensive queries
- if ((searchLong!=false) && word.length > 4) {
- var message = "Searching Descriptions for more than four words " +
- "will take a very long time indeed. Please choose " +
- "no more than four keywords for your query.";
- alert(message);
- return;
- }
- var searchURL = make_query_URL(url, inputstring, searchLong);
- if (searchURL != no_result) {
- go_to(searchURL);
- //window.open(searchURL, "other" );
- } else {
- return;
- }
-}
-
-//
-// original interface, untested
-//
-//function SearchForBugs (input, searchRadio) {
-// if (searchRadio[0].checked) {
-// return Search(bugzilla + "buglist.cgi", input, false);
-// } else {
-// return Search(bugzilla + "buglist.cgi", input, true);
-// }
-//}
-
-// derived from http://www.cs.hmc.edu/~jruderma/s/bugz.html
-
-// QuickSearch combines lookup-by-bug-number and search
-// in a single textbox.
-//
-// type nothing:
-// --> go to bugzilla front page
-// type a number:
-// --> go to that bug number
-// type several numbers, separated by commas:
-// --> go to a buglist of just those bug numbers
-// type anything else:
-// --> search summary, product, component, keywords, status whiteboard
-// (and URL if it's an IP address, a host.name, or an absolute://URL)
-
-function QuickSearch (input)
-{
- //remove leading and trailing whitespace
- input = input.replace(/^[\s]+/,"").replace(/[\s]+$/,"");
-
- if (input == "")
- {
- //once this _is_ on http://bugzilla.mozilla.org, it should just return;
- go_to(bugzilla);
- }
- else if (input.match(/^[0-9, ]*$/))
- {
- if (input.indexOf(",") == -1) {
- // only _one_ bug number --> show_bug
- go_to(bugzilla+"show_bug.cgi?id="+escape(input));
- } else {
- // comma-separated bug numbers --> buglist
- go_to(bugzilla+"buglist.cgi?bug_id="+escape(input)
- + "&bugidtype=include&order=bugs.bug_id");
- }
- }
- else
- {
- Search(bugzilla+"buglist.cgi",input,false);
- }
- return;
-}
-
-function LoadQuery(input) {
- //remove leading and trailing whitespace
- input = input.replace(/^[\s]+/,"").replace(/[\s]+$/,"");
-
- Search(bugzilla+"query.cgi",input,false);
- return;
-}
-
diff --git a/quicksearchhack.html b/quicksearchhack.html
deleted file mode 100644
index d514082f8..000000000
--- a/quicksearchhack.html
+++ /dev/null
@@ -1,357 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <title>Bugzilla QuickSearch (for Hackers)</title>
-</head>
-
-<body bgcolor="#ffffff">
-
-<script src="localconfig.js" type="text/javascript"></script>
-<script src="quicksearch.js" type="text/javascript"></script>
-
-<h1>Bugzilla QuickSearch (for Hackers)</h1>
-
-<p>
-Type in one or more words (or word fragments) to search for:
-</p>
-
-<form name="f" action="show_bug.cgi" method="get"
- onsubmit="QuickSearch(f.id.value); return false;">
- <table>
- <tr>
- <td><input type="text" size="40" name="id"></td>
- <td align="left"><input type="submit" name="run" value="Search"></td>
- <td align="left"><input type="button" name="load" value="Load Query"
- onclick="LoadQuery(f.id.value);">
- </td>
- </tr>
- </table>
-</form>
-
-<script type="text/javascript">
-<!--
-document.forms['f'].id.focus();
-//-->
-</script>
-
-<p>
-This is a case-insensitive ``all words as substrings'' search;
-words are separated by spaces.
-By default, the following fields are relevant: Summary, Keywords,
-Product, Component, Status Whiteboard. If a word looks like a part of a
-URL, that field is included in the search, too.
-</p>
-<p>
-The generic format for a ``word'' is
-&nbsp;<tt>field1,...,fieldN:value1,...,valueM</tt>&nbsp;.
-A bug qualifies if at least one of the values occurs as a substring in
-at least one of the fields.
-For example, &nbsp;<tt>assignee,reporter,qa:ibm,sun</tt>&nbsp;
-will give you bugs where the assignee, reporter, or qa contact
-has an email address that contains
-&nbsp;<tt>ibm</tt>&nbsp; or &nbsp;<tt>sun</tt>&nbsp;.
-If only &nbsp;<tt>value1,...,valueM</tt>&nbsp; is given,
-the prefix (roughly) defaults to &nbsp;<tt>summary,keywords,product,component,statuswhiteboard:</tt>&nbsp; as noted above.
-You can use &nbsp;<tt>-<i>word</i></tt>&nbsp; to express the logical negation
-of &nbsp;<tt><i>word</i></tt>.&nbsp;
-</p>
-<p>
-Here is a complete listing of available fields (the Shortcut column is just
-for access speed):
-</p>
-
-<table border="1">
-<thead>
-<tr>
- <td><b>Searched by default</b></td>
- <td><b>Shortcut</b></td>
- <td><b>Field Name</b></td>
- <td><b>Aliases</b></td>
- <td><b>Description</b></td>
-</tr>
-</thead>
-
-<!-- Status, Resolution, Platform, OS, Priority, Severity -->
-
-<tr>
- <td>&nbsp;</td>
- <td rowspan="2"><tt>UNCO,NEW,...,CLOS,<br>FIX,DUP,...<i>(as first word)</i></tt></td>
- <td><tt>status</tt></td>
- <td>&nbsp;</td>
- <td><a href="page.cgi?id=fields.html#status">Status</a>
- <i>("bug_status")</i>
- </td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td><tt>resolution</tt></td>
- <td>&nbsp;</td>
- <td><a href="page.cgi?id=fields.html#resolution">Resolution</a></td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td><i>as-is</i></td>
- <td><tt>platform</tt></td>
- <td>&nbsp;</td>
- <td><a href="page.cgi?id=fields.html#rep_platform">Platform</a> <i>("rep_platform")</i></td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td><tt>os</tt></td>
- <td><tt>opsys</tt></td>
- <td><a href="page.cgi?id=fields.html#op_sys">OS</a> <i>("op_sys")</i></td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td><tt>p1,p2</tt> <i>or</i> <tt>p1-2</tt></td>
- <td><tt>priority</tt></td>
- <td><tt>pri</tt></td>
- <td><a href="page.cgi?id=fields.html#priority">Priority</a></td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td><tt>blo,cri,...,enh</tt></td>
- <td><tt>severity</tt></td>
- <td><tt>sev</tt></td>
- <td><a href="page.cgi?id=fields.html#bug_severity">Severity</a> <i>("bug_severity")</i></td>
-</tr>
-
-<!-- People: AssignedTo, Reporter, QA Contact, CC, Added comment -->
-<!-- Added comment is missing!!!! -->
-
-<tr>
- <td>&nbsp;</td>
- <td><b>@</b><i>assignee</i></td>
- <td><tt>assignedto</tt></td>
- <td><tt>assignee, owner</tt></td>
- <td><a href="page.cgi?id=fields.html#assigned_to">Assignee</a> <i>("assigned_to")</i></td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td><tt>reporter</tt></td>
- <td><tt>rep</tt></td>
- <td>Reporter (email)</td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td><tt>qa</tt></td>
- <td><tt>qacontact</tt></td>
- <td>QA Contact (email) <i>("qa_contact")</i></td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td><tt>cc</tt></td>
- <td>&nbsp;</td>
- <td>CC (email)</td>
-</tr>
-
-<!-- Product, Version, Component, Target Milestone -->
-
-<tr>
- <td><i>yes</i></td>
- <td rowspan="2"><b>:</b><i>area</i></td>
- <td><tt>product</tt></td>
- <td><tt>prod</tt></td>
- <td>Product (enum)</td>
-</tr>
-<tr>
- <td><i>yes</i></td>
- <td><tt>component</tt></td>
- <td><tt>comp</tt></td>
- <td><a href="describecomponents.cgi">Component</a></td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td><tt>version</tt></td>
- <td><tt>ver</tt></td>
- <td>Version (enum)</td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td><tt>milestone</tt></td>
- <td><tt>target, targetmilestone</tt></td>
- <td>Target Milestone <i>("target_milestone")</i></td>
-</tr>
-
-<!-- Summary, Description, URL, Status whiteboard, Keywords -->
-
-<tr>
- <td><i>yes</i></td>
- <td>&nbsp;</td>
- <td><tt>summary</tt></td>
- <td><tt>shortdesc</tt></td>
- <td>Bug Summary (short text)<i>("short_desc")</i></td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td><tt>description</tt></td>
- <td><tt>desc, longdesc<!--, comment--></tt></td>
- <!-- reserve "comment" for "added comment" email search?! -->
- <td>Bug Description / Comments (long text)</td>
-</tr>
-<tr>
- <td><i>depends</i></td>
- <td>&nbsp;</td>
- <td><tt>url</tt></td>
- <td>&nbsp;</td>
- <td>URL <i>("bug_file_loc")</i></td>
-</tr>
-<tr>
- <td><i>yes</i></td>
- <td>&nbsp;</td>
- <td><tt>statuswhiteboard</tt></td>
- <td><tt>sw, whiteboard</tt></td>
- <td>Status Whiteboard <i>("status_whiteboard")</i></td>
-</tr>
-<tr>
- <td><i>yes</i></td>
- <td><b>!</b><i>keyword</i></td>
- <td><tt>keywords</tt></td>
- <td><tt>kw</tt></td>
- <td><a href="describekeywords.cgi">Keywords</a></td>
-</tr>
-
-<!-- Attachments -->
-
-<tr>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td><tt>attachmentdesc</tt></td>
- <td><tt>attachdesc</tt></td>
- <td>Attachment Description <i>("attachments.description")</i></td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td><tt>attachmentdata</tt></td>
- <td><tt>attachdata</tt></td>
- <td>Attachment Data <i>("attachments.thedata")</i></td>
-</tr>
-<tr>
- <td>&nbsp;</td>
- <td>&nbsp;</td>
- <td><tt>attachmentmimetype</tt></td>
- <td><tt>attachmimetype</tt></td>
- <td>Attachment mime-type <i>("attachments.mimetype")</i></td>
-</tr>
-
-</table>
-
-<p>
-Examples for some useful abbreviations:
-</p>
-<table border="1">
-<thead>
-<tr>
- <td><b>Syntax</b></td>
- <td><b>Semantics and Examples</b></td>
-</tr>
-</thead>
-
-<!--
-<tr>
- <td><i>STAT</i> <i>(as first word)</i></td>
- <td><b>status,resolution:</b><i>STAT</i></td>
-</tr>
-<tr>
- <td></td>
- <td></td>
-</tr>
-<tr>
- <td><tt>ALL</tt> <i>(as first word)</i></td>
- <td><i>include all resolved bugs in your query</i></td>
-</tr>
-<tr>
- <td><tt>+DUP,FIXED</tt> <i>(as first word)</i></td>
- <td><i>include DUPLICATE and FIXED bugs in your search</i></td>
-</tr>
--->
-
-<tr>
- <td><b>:</b><i>area</i></td>
- <td><b>product,component:</b><i>area</i></td>
-</tr>
-<!--
-<tr>
- <td><tt>:browser</tt></td>
- <td><i>bugs in the Browser product</i></td>
-</tr>
- <td><tt>:mail</tt></td>
- <td><i>bugs in the MailNews product</td>
-</tr>
-<tr>
- <td><tt>:xbl</tt></td>
- <td><i>bugs in the XBL component</i></td>
-</tr>
- -->
-<tr>
- <td><i>sev</i></td>
- <td><b>severity:</b><i>sev</i></td>
-</tr>
-<tr>
- <td><tt>blo,cri,maj</tt></td>
- <td><i>severe bugs</i></td>
-</tr>
-<tr>
- <td><tt>enh</tt></td>
- <td><i>enhancement requests</i></td>
-</tr>
-<tr>
- <td><b>p</b><i>level</i></td>
- <td><b>priority:</b><i>level</i></td>
-</tr>
-<tr>
- <td><tt>p1</tt></td>
- <td><i>very high-priority bugs</i></td>
-</tr>
-<tr>
- <td><tt>p1-2</tt></td>
- <td><i>high-priority bugs</i></td>
-</tr>
-<tr>
- <td><b>@</b><i>assignee</i></td>
- <td><b>assignedto:</b><i>assignee</i></td>
-</tr>
-<!--
-<tr>
- <td><tt>@nobody</tt></td>
- <td><i>ownerless bugs</i></td>
-</tr>
-<tr>
- <td><tt>@mozilla.org</tt></td>
- <td><i>bugs assigned to mozilla.org members</i></td>
-</tr>
- -->
-<tr>
- <td><b>!</b><i>keyword</i></td>
- <td><b>keywords:</b><i>keyword</i></td>
-</tr>
-<!--
-<tr>
- <td><tt>!crash</tt></td>
- <td><i>crasher bugs</i></td>
-</tr>
-<tr>
- <td><tt>!helpwanted</tt></td>
- <td><i>bugs waiting for your help</i></td>
-</tr>
- -->
-</table>
-
-<p>
-More information can be found in the
-<a href="quicksearch.html#features">&quot;Features&quot;</a> section
-on the <a href="quicksearch.html">introductory page</a>.
-</p>
-
-</body>
-</html>
-
diff --git a/skins/standard/global.css b/skins/standard/global.css
index 4c265df1e..ea95e7460 100644
--- a/skins/standard/global.css
+++ b/skins/standard/global.css
@@ -176,13 +176,14 @@ body
margin-top: 5px;
width: 100%;
font-family: sans-serif;
+ background: #edf2f2;
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
}
#footer form
{
- background: #edf2f2;
- border-top: 1px solid #ddd;
- border-bottom: 1px solid #ddd;
+ display: inline;
}
#footer span
diff --git a/template/en/default/config.js.tmpl b/template/en/default/config.js.tmpl
index a74c5d34d..e3ec91435 100644
--- a/template/en/default/config.js.tmpl
+++ b/template/en/default/config.js.tmpl
@@ -19,8 +19,7 @@
# Contributor(s): Myk Melez <myk@mozilla.org>
#%]
//
-// This file contains the installation specific values for QuickSearch
-// and other Bugzilla clients. See quicksearch.js for more details.
+// This file contains installation specific values for third-party clients.
//
// Note: this interface is experimental and under development.
// We may and probably will make breaking changes to it in the future.
diff --git a/template/en/default/global/useful-links.html.tmpl b/template/en/default/global/useful-links.html.tmpl
index 38b193cf5..5a01a5703 100644
--- a/template/en/default/global/useful-links.html.tmpl
+++ b/template/en/default/global/useful-links.html.tmpl
@@ -25,7 +25,6 @@
[% PROCESS global/variables.none.tmpl %]
-<form method="get" action="show_bug.cgi">
<div id="useful-links">
<div id="links-actions">
<div class="label">Actions:</div>
@@ -34,8 +33,13 @@
<a href="enter_bug.cgi">New</a> |
<a href="query.cgi">Search</a> |
- [% terms.bug %] # <input class="txt" name="id" size="6">
- <input class="btn" type="submit" value="Find"> |
+ <form action="buglist.cgi" method="get"
+ onsubmit="if (this.quicksearch.value == '')
+ { alert('Please enter one or more search terms first.');
+ return false; } return true;">
+ <input class="txt" type="text" name="quicksearch">
+ <input class="btn" type="submit" value="Find">
+ </form> |
<a href="report.cgi">Reports</a>
@@ -127,4 +131,3 @@
[%# Sections of links to more things users can do on this installation. %]
[% Hook.process("end") %]
</div>
-</form>
diff --git a/template/en/default/index.html.tmpl b/template/en/default/index.html.tmpl
index eb1cbbd58..a19334c30 100644
--- a/template/en/default/index.html.tmpl
+++ b/template/en/default/index.html.tmpl
@@ -28,11 +28,12 @@
[% PROCESS global/variables.none.tmpl %]
-[% title = BLOCK %]
-[% terms.Bugzilla %] Main Page
-[% END %]
-[% style_urls = [ "skins/standard/index.css" ] %]
-[% PROCESS global/header.html.tmpl %]
+
+[% PROCESS global/header.html.tmpl
+ title = "$terms.Bugzilla Main Page"
+ style_urls = [ 'skins/standard/index.css' ]
+ onload = 'document.forms[\'f\'].quicksearch.focus();'
+%]
<script type="text/javascript">
@@ -84,25 +85,19 @@ function addSidebar() {
</ul>
- <form id="show-bug" name="f" action="show_bug.cgi" method="get"
- onsubmit="QuickSearch(f.id.value); return false;">
+ <form id="show-bug" name="f" action="buglist.cgi" method="get"
+ onsubmit="if (this.quicksearch.value == '')
+ { alert('Please enter one or more search terms first.');
+ return false; } return true;">
<div>
<p>Enter [% terms.abug %] # or some search terms:</p>
- <input id="text" type="text" name="id">
- <input id="show" type="submit" value="Show">
- <a href="quicksearch.html">[Help]</a>
+ <input id="quicksearch" type="text" name="quicksearch">
+ <input id="find" type="submit" value="Find">
+ <a href="page.cgi?id=quicksearch.html">[Help]</a>
</div>
</form>
<div class="outro"></div>
</div>
-<script type="text/javascript" src="localconfig.js"></script>
-<script type="text/javascript" src="quicksearch.js"></script>
-<script type="text/javascript">
-<!--
-document.forms['f'].id.focus();
-//-->
-</script>
-
[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/pages/quicksearch.html.tmpl b/template/en/default/pages/quicksearch.html.tmpl
new file mode 100644
index 000000000..73a0172ee
--- /dev/null
+++ b/template/en/default/pages/quicksearch.html.tmpl
@@ -0,0 +1,190 @@
+[%# 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.
+ #
+ # Contributor(s): N.N.
+ # Marc Schumann <wurblzap@gmail.com>
+ #%]
+
+[% PROCESS global/variables.none.tmpl %]
+
+[% INCLUDE global/header.html.tmpl
+ title = "$terms.Bugzilla QuickSearch",
+ style = 'ul {margin-bottom: 2ex}
+ ul li {margin-top: 2ex}
+ ul li ul li {margin-top: 0}'
+ onload = 'document.forms[\'f\'].quicksearch.focus()'
+ %]
+
+<p style="font-size: 80%">
+ If you are already familiar with the original
+ <a href="query.cgi">[% terms.Bugzilla %] Search Form</a>,
+ you may prefer <a href="page.cgi?id=quicksearchhack.html">this form</a>.
+</p>
+
+<p>
+ Type in one or more words (or word fragments) to search for:
+</p>
+
+<form name="f" action="buglist.cgi" method="get"
+ onsubmit="if (this.quicksearch.value == '')
+ { alert('Please enter one or more search terms first.');
+ return false; } return true;">
+ <input type="text" size="40" name="quicksearch">
+ <input type="submit" value="Find">
+</form>
+
+<h2>Getting Started</h2>
+
+<ul>
+ <li>
+ This is <strong>case-insensitive</strong> search:<br />
+ <ul>
+ <li><tt>table</tt>, <tt>Table</tt> and <tt>TABLE</tt> are all the same.</li>
+ </ul>
+ </li>
+ <li>
+ This is <strong>all words as substrings</strong>
+ search.<br />
+ Therefore you should <strong>use stems</strong> to get better results:
+ <ul>
+ <li>
+ Use <tt>localiz</tt> instead of <tt>localize</tt> or
+ <tt>localization</tt>.
+ </li>
+ <li>
+ Use <tt>bookmark</tt> instead of <tt>bookmarks</tt> or
+ <tt>bookmarking</tt>.
+ </li>
+ </ul>
+ </li>
+</ul>
+
+<h2><a name="features">Features</a></h2>
+
+<ul>
+ <li>
+ Boolean operations: &ldquo;<tt>-foo</tt>&rdquo;&nbsp;(NOT),
+ &ldquo;<tt>foo&nbsp;bar</tt>&rdquo;&nbsp;(AND),
+ &ldquo;<tt>foo|bar</tt>&rdquo;&nbsp;(OR).
+ <ul>
+ <li>
+ <strong>NOT</strong>:<br />
+ Use <tt><b>-</b><i>foo</i></tt> to exclude [% terms.bugs %]
+ with <tt><i>foo</i></tt> in the summary.
+ </li>
+ <li>
+ <strong>AND</strong>:<br />
+ Space-separated words are treated as a conjunction.
+ </li>
+ <li>
+ <strong>OR</strong>:<br />
+ Within a word, "|"-separated parts denote alternatives.
+ </li>
+ <li>
+ Besides "|", a comma can be used to separate alternatives.
+ </li>
+ <li>
+ OR has higher precedence than AND; AND is the top level operation.
+ </li>
+ </ul>
+ <i>Example:</i>
+ <tt>url,location bar,field -focus</tt> means
+ (<tt>url</tt> OR <tt>location</tt>) AND (<tt>bar</tt> OR <tt>field</tt>)
+ AND (NOT <tt>focus</tt>)
+ </li>
+ <li>
+ Use <tt>+foo</tt> to search for [% terms.bugs %] where the
+ <strong>summary</strong> contains <tt>foo</tt> as a
+ <strong>substring</strong>.<br/>
+ Use <tt>#foo</tt> to search for [% terms.bugs %] where the
+ <strong>summary</strong> contains the <strong>word</strong> <tt>foo</tt>.
+ <ul>
+ <li>
+ <tt>+brow</tt> does not find all [% terms.bugs %] in the
+ <tt>Browser</tt> product.
+ </li>
+ <li>
+ <tt>#title</tt> does not find [% terms.bugs %] with <tt>titlebar</tt>
+ or <tt>titled</tt>.
+ </li>
+ </ul>
+ Phrases with special chars (space, comma, +, -, #, &hellip;) can be
+ <strong>quoted</strong>:
+ <ul>
+ <li>
+ <tt>"lock icon"</tt>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <strong>Open vs. Resolved [% terms.Bugs %]</strong>:<br />
+ By default, only open (i.e. unresolved) [% terms.bugs %] are shown.
+ Use <tt>+DUP</tt> as first word in your search to include duplicate
+ [%+ terms.bugs %] in your search,
+ <tt>FIXED</tt> to search for fixed [%+ terms.bugs %] only,
+ or <tt>ALL</tt> to search all [% terms.bugs %],
+ regardless of status or resolution.
+ Searching for duplicates is recommended if you can't find an open
+ [%+ terms.bug %] directly.
+ <ul>
+ <li>
+ <tt>+DUP,FIXED table border</tt>
+ </li>
+ <li>
+ <tt>ALL mouse wheel</tt>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <strong>Focus the Search with Products &amp;
+ Components</strong>:<br />
+ To search for [% terms.bugs %] in product "Foo Bar" only, add
+ <tt>:foo</tt> or <tt>:bar</tt> or both to your search.
+ You can do this with any substring of a
+ <a href="describecomponents.cgi">product or component</a> to focus the
+ search.
+ </li>
+</ul>
+
+<h2>More Tips</h2>
+
+<ul>
+ <li>
+ You can also use this tool to <strong>lookup</strong> a [% terms.bug %] by
+ its number:<br />
+ <ul>
+ <li><tt>12345</tt></li>
+ </ul>
+ </li>
+ <li>
+ A comma-separated list of [% terms.bug %] numbers gives you a list of these
+ [%+ terms.bugs %]:<br />
+ <ul>
+ <li><tt>12345,23456,34567</tt></li>
+ </ul>
+ </li>
+</ul>
+
+<p>
+ By default, the following fields are searched: Summary, Keywords, Product,
+ Component, Status Whiteboard. If a word looks like a part of a URL, that field
+ is included in the search, too.
+</p>
+<hr>
+
+<p>
+ Use the powerful <a href="query.cgi">[% terms.Bugzilla %] Search Form</a>
+ for advanced queries.
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/pages/quicksearchhack.html.tmpl b/template/en/default/pages/quicksearchhack.html.tmpl
new file mode 100644
index 000000000..529484991
--- /dev/null
+++ b/template/en/default/pages/quicksearchhack.html.tmpl
@@ -0,0 +1,377 @@
+[%# 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.
+ #
+ # Contributor(s): N.N.
+ # Marc Schumann <wurblzap@gmail.com>
+ #%]
+
+[% PROCESS global/variables.none.tmpl %]
+
+[% INCLUDE global/header.html.tmpl
+ title = "$terms.Bugzilla QuickSearch (for Hackers)",
+ style = 'th {text-align: left}'
+ onload = 'document.forms[\'f\'].quicksearch.focus()'
+ %]
+
+<p>
+ Type in one or more words (or word fragments) to search for:
+</p>
+
+<form name="f" action="buglist.cgi" method="get"
+ onsubmit="if (this.quicksearch.value == '')
+ { alert('Please enter one or more search terms first.');
+ return false; } return true;">
+ <input type="text" size="40" name="quicksearch">
+ <input type="submit" value="Find">
+ <input type="submit" name="load" value="Load Search Form">
+</form>
+
+<p>
+ This is a case-insensitive &ldquo;all words as substrings&rdquo; search;
+ words are separated by spaces.
+ By default, the following fields are relevant: Summary, Keywords,
+ Product, Component, Status Whiteboard.
+ If a word looks like a part of a URL, that field is included in the search,
+ too.
+</p>
+<p>
+ The generic format for a &ldquo;word&rdquo; is
+ <tt>field1,&hellip;,fieldN:value1,&hellip;,valueM</tt>.
+ A [% terms.bug %] qualifies if at least one of the values occurs as a
+ substring in at least one of the fields.
+ For example, <tt>assignee,reporter,qa:ibm,sun</tt> will give you
+ [%+ terms.bugs %] where the assignee, reporter, or qa contact has a login
+ that contains <tt>ibm</tt> or <tt>sun</tt>.
+ If only <tt>value1,&hellip;,valueM</tt> is given, the prefix (roughly) defaults to
+ <tt>summary,keywords,product,component,statuswhiteboard:</tt> as noted above.
+ You can use <tt>-<i>word</i></tt> to express the logical negation of
+ <tt><i>word</i></tt>.
+</p>
+<p>
+ Here is a complete listing of available fields (the Shortcut column is just
+ for access speed):
+</p>
+
+<table border="1">
+<thead>
+<tr>
+ <th>Searched by default</th>
+ <th>Shortcut</th>
+ <th>Field Name</th>
+ <th>Aliases</th>
+ <th>Description</th>
+</tr>
+</thead>
+
+<!-- Status, Resolution, Platform, OS, Priority, Severity -->
+
+<tr>
+ <td>&nbsp;</td>
+ <td rowspan="2">
+ <tt>UNCO,NEW,&hellip;,CLOS,<br>FIX,DUP,&hellip;<i>(as first word)</i></tt>
+ </td>
+ <td><tt>status</tt></td>
+ <td>&nbsp;</td>
+ <td>
+ <a href="page.cgi?id=fields.html#status">Status</a>
+ <i>(&ldquo;bug_status&rdquo;)</i>
+ </td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td><tt>resolution</tt></td>
+ <td>&nbsp;</td>
+ <td><a href="page.cgi?id=fields.html#resolution">Resolution</a></td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td><i>as-is</i></td>
+ <td><tt>platform</tt></td>
+ <td>&nbsp;</td>
+ <td>
+ <a href="page.cgi?id=fields.html#rep_platform">Platform</a>
+ <i>(&ldquo;rep_platform&rdquo;)</i>
+ </td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><tt>os</tt></td>
+ <td><tt>opsys</tt></td>
+ <td>
+ <a href="page.cgi?id=fields.html#op_sys">OS</a>
+ <i>(&ldquo;op_sys&rdquo;)</i>
+ </td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td><tt>p1,p2</tt> <i>or</i> <tt>p1-2</tt></td>
+ <td><tt>priority</tt></td>
+ <td><tt>pri</tt></td>
+ <td><a href="page.cgi?id=fields.html#priority">Priority</a></td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td><tt>blo,cri,&hellip;,enh</tt></td>
+ <td><tt>severity</tt></td>
+ <td><tt>sev</tt></td>
+ <td>
+ <a href="page.cgi?id=fields.html#bug_severity">Severity</a>
+ <i>(&ldquo;bug_severity&rdquo;)</i>
+ </td>
+</tr>
+
+<!-- People: AssignedTo, Reporter, QA Contact, CC, Added comment -->
+<!-- Added comment is missing!!!! -->
+
+<tr>
+ <td>&nbsp;</td>
+ <td><b>@</b><i>assignee</i></td>
+ <td><tt>assignedto</tt></td>
+ <td><tt>assignee</tt></td>
+ <td>
+ <a href="page.cgi?id=fields.html#assigned_to">Assignee</a>
+ <i>(&ldquo;assigned_to&rdquo;)</i>
+ </td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><tt>reporter</tt></td>
+ <td><tt>rep</tt></td>
+ <td>Reporter (login)</td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><tt>qa</tt></td>
+ <td><tt>qacontact</tt></td>
+ <td>QA Contact (login) <i>(&ldquo;qa_contact&rdquo;)</i></td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><tt>cc</tt></td>
+ <td>&nbsp;</td>
+ <td>CC (login)</td>
+</tr>
+
+<!-- Product, Version, Component, Target Milestone -->
+
+<tr>
+ <td><i>yes</i></td>
+ <td rowspan="2"><b>:</b><i>area</i></td>
+ <td><tt>product</tt></td>
+ <td><tt>prod</tt></td>
+ <td>Product (enum)</td>
+</tr>
+<tr>
+ <td><i>yes</i></td>
+ <td><tt>component</tt></td>
+ <td><tt>comp</tt></td>
+ <td><a href="describecomponents.cgi">Component</a></td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><tt>version</tt></td>
+ <td><tt>ver</tt></td>
+ <td>Version (enum)</td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><tt>milestone</tt></td>
+ <td><tt>target, targetmilestone</tt></td>
+ <td>Target Milestone <i>(&ldquo;target_milestone&rdquo;)</i></td>
+</tr>
+
+<!-- Summary, Description, URL, Status whiteboard, Keywords -->
+
+<tr>
+ <td><i>yes</i></td>
+ <td>&nbsp;</td>
+ <td><tt>summary</tt></td>
+ <td><tt>shortdesc</tt></td>
+ <td>
+ [% terms.Bug %] Summary (short text)
+ <i>(&ldquo;short_desc&rdquo;)</i>
+ </td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><tt>description</tt></td>
+ <td><tt>desc, longdesc<!--, comment--></tt></td>
+ <!-- reserve "comment" for "added comment" login search?! -->
+ <td>[% terms.Bug %] Description / Comments (long text)</td>
+</tr>
+<tr>
+ <td><i>depends</i></td>
+ <td>&nbsp;</td>
+ <td><tt>url</tt></td>
+ <td>&nbsp;</td>
+ <td>URL <i>(&ldquo;bug_file_loc&rdquo;)</i></td>
+</tr>
+<tr>
+ <td><i>yes</i></td>
+ <td>&nbsp;</td>
+ <td><tt>statuswhiteboard</tt></td>
+ <td><tt>sw, whiteboard</tt></td>
+ <td>Status Whiteboard <i>(&ldquo;status_whiteboard&rdquo;)</i></td>
+</tr>
+<tr>
+ <td><i>yes</i></td>
+ <td><b>!</b><i>keyword</i></td>
+ <td><tt>keywords</tt></td>
+ <td><tt>kw</tt></td>
+ <td><a href="describekeywords.cgi">Keywords</a></td>
+</tr>
+
+<!-- Attachments -->
+
+<tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><tt>attachmentdesc</tt></td>
+ <td><tt>attachdesc</tt></td>
+ <td>
+ Attachment Description
+ <i>(&ldquo;attachments.description&rdquo;)</i>
+ </td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><tt>attachmentdata</tt></td>
+ <td><tt>attachdata</tt></td>
+ <td>Attachment Data <i>(&ldquo;attachments.thedata&rdquo;)</i></td>
+</tr>
+<tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><tt>attachmentmimetype</tt></td>
+ <td><tt>attachmimetype</tt></td>
+ <td>Attachment mime-type <i>(&ldquo;attachments.mimetype&rdquo;)</i></td>
+</tr>
+
+</table>
+
+<p>
+ Examples for some useful abbreviations:
+</p>
+<table border="1">
+<thead>
+<tr>
+ <th>Syntax</th>
+ <th>Semantics and Examples</th>
+</tr>
+</thead>
+
+<!--
+<tr>
+ <td><i>STAT</i> <i>(as first word)</i></td>
+ <td><b>status,resolution:</b> <i>STAT</i></td>
+</tr>
+<tr>
+ <td></td>
+ <td></td>
+</tr>
+<tr>
+ <td><tt>ALL</tt> <i>(as first word)</i></td>
+ <td><i>include all resolved [% terms.bugs %] in your search</i></td>
+</tr>
+<tr>
+ <td><tt>+DUP,FIXED</tt> <i>(as first word)</i></td>
+ <td><i>include DUPLICATE and FIXED [% terms.bugs %] in your search</i></td>
+</tr>
+-->
+
+<tr>
+ <td><b>:</b><i>area</i></td>
+ <td><b>product,component:</b><i>area</i></td>
+</tr>
+<!--
+<tr>
+ <td><tt>:browser</tt></td>
+ <td><i>[% terms.bugs %] in the Browser product</i></td>
+</tr>
+ <td><tt>:mail</tt></td>
+ <td><i>[% terms.bugs %] in the MailNews product</td>
+</tr>
+<tr>
+ <td><tt>:xbl</tt></td>
+ <td><i>[% terms.bugs %] in the XBL component</i></td>
+</tr>
+ -->
+<tr>
+ <td><i>sev</i></td>
+ <td><b>severity:</b><i>sev</i></td>
+</tr>
+<tr>
+ <td><tt>blo,cri,maj</tt></td>
+ <td><i>severe [% terms.bugs %]</i></td>
+</tr>
+<tr>
+ <td><tt>enh</tt></td>
+ <td><i>enhancement requests</i></td>
+</tr>
+<tr>
+ <td><b>p</b><i>level</i></td>
+ <td><b>priority:</b><i>level</i></td>
+</tr>
+<tr>
+ <td><tt>p1</tt></td>
+ <td><i>very high-priority [% terms.bugs %]</i></td>
+</tr>
+<tr>
+ <td><tt>p1-2</tt></td>
+ <td><i>high-priority [% terms.bugs %]</i></td>
+</tr>
+<tr>
+ <td><b>@</b><i>assignee</i></td>
+ <td><b>assignedto:</b><i>assignee</i></td>
+</tr>
+<!--
+<tr>
+ <td><tt>@nobody</tt></td>
+ <td><i>assigneeless [% terms.bugs %]</i></td>
+</tr>
+<tr>
+ <td><tt>@mozilla.org</tt></td>
+ <td><i>[% terms.bugs %] assigned to mozilla.org members</i></td>
+</tr>
+ -->
+<tr>
+ <td><b>!</b><i>keyword</i></td>
+ <td><b>keywords:</b><i>keyword</i></td>
+</tr>
+<!--
+<tr>
+ <td><tt>!crash</tt></td>
+ <td><i>crasher [% terms.bugs %]</i></td>
+</tr>
+<tr>
+ <td><tt>!helpwanted</tt></td>
+ <td><i>[% terms.bugs %] waiting for your help</i></td>
+</tr>
+ -->
+</table>
+
+<p>
+ More information can be found in the
+ <a href="page.cgi?id=quicksearch.html#features">&ldquo;Features&rdquo;</a>
+ section on the <a href="page.cgi?id=quicksearch.html">introductory page</a>.
+</p>
+
+[% PROCESS global/footer.html.tmpl %]
diff --git a/template/en/default/sidebar.xul.tmpl b/template/en/default/sidebar.xul.tmpl
index b04aa08dc..31f0a2c6b 100644
--- a/template/en/default/sidebar.xul.tmpl
+++ b/template/en/default/sidebar.xul.tmpl
@@ -34,14 +34,8 @@
orient="vertical"
onload="document.getElementById('query-field').addEventListener('keypress', initial_keypress_handler, true)">
-<!-- Load QuickSearch libraries -->
-<script type="application/x-javascript" src="localconfig.js"/>
-<script type="application/x-javascript" src="quicksearch.js"/>
<script type="application/x-javascript"><![CDATA[
-// Tell QuickSearch that the source of this is the sidebar
-var sidebar = 1;
-
function load_absolute_url( aAbsoluteURL ) {
content.location = aAbsoluteURL;
}
@@ -59,7 +53,7 @@ function initial_keypress_handler( aEvent ) {
function normal_keypress_handler( aEvent ) {
if ( aEvent.keyCode == 13 )
- QuickSearch(this.value);
+ load_relative_url('buglist.cgi?quicksearch=' + this.value);
}
]]></script>