diff options
author | cyeh%bluemartini.com <> | 2001-03-01 07:07:24 +0000 |
---|---|---|
committer | cyeh%bluemartini.com <> | 2001-03-01 07:07:24 +0000 |
commit | 5b2994b0ce4cf27709b3742a2b63a680464662a0 (patch) | |
tree | ac2b46dde7b3a19475df1a8400e99bc3c120e283 | |
parent | d0605ef9490b55c38d090c21b5993eda143e7e86 (diff) | |
download | bugs-5b2994b0ce4cf27709b3742a2b63a680464662a0.tar bugs-5b2994b0ce4cf27709b3742a2b63a680464662a0.tar.gz bugs-5b2994b0ce4cf27709b3742a2b63a680464662a0.tar.bz2 bugs-5b2994b0ce4cf27709b3742a2b63a680464662a0.tar.xz bugs-5b2994b0ce4cf27709b3742a2b63a680464662a0.zip |
fix for 69793: check in new files for QuickSearch
patch contributed by franke@ags.uni-sb.de (Andreas Franke)
Now add quicksearch functionality to the main index page.
-rw-r--r-- | index.html | 22 | ||||
-rw-r--r-- | localconfig.js | 75 | ||||
-rw-r--r-- | quicksearch.html | 146 | ||||
-rw-r--r-- | quicksearch.js | 670 | ||||
-rw-r--r-- | quicksearchhack.html | 350 |
5 files changed, 1258 insertions, 5 deletions
diff --git a/index.html b/index.html index 566a1053b..3a1a76ff6 100644 --- a/index.html +++ b/index.html @@ -76,11 +76,23 @@ But it all boils down to a choice of: <a href="createaccount.cgi">Open a new Bugzilla account</a><br> <a href="relogin.cgi">Forget the currently stored login</a><br> <a href="userprefs.cgi">Change password or user preferences</a><br> -<FORM METHOD=GET ACTION="show_bug.cgi"> -<INPUT TYPE=SUBMIT VALUE="Find"> bug # <INPUT NAME=id SIZE=6></FORM> -<SCRIPT LANGUAGE="JavaScript"> -document.forms[0].id.focus() -</SCRIPT> +<p> +<script language="JavaScript" src="localconfig.js"></script> +<script language="JavaScript" src="quicksearch.js"></script> + +<form name="f" action="show_bug.cgi" method="get" + onsubmit="QuickSearch(); return false;"> + Enter a bug # or some search terms:<br> + <input type="text" name="id"> + <input type="submit" value="Show"> + <a href="quicksearch.html">[Help]</a> +</form> + +<script> +<!-- +document.forms['f'].id.focus(); +//--> +</script> </BODY> </HTML> diff --git a/localconfig.js b/localconfig.js new file mode 100644 index 000000000..7cb01eb74 --- /dev/null +++ b/localconfig.js @@ -0,0 +1,75 @@ +// +// 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 new file mode 100644 index 000000000..900180065 --- /dev/null +++ b/quicksearch.html @@ -0,0 +1,146 @@ +<html> +<head> + <title>Bugzilla QuickSearch</title> +</head> + +<body bgcolor="#ffffff"> + +<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"></script> +<script src="quicksearch.js"></script> + +<h1>Bugzilla QuickSearch</h1> + +Type in one or more words (or word fragments) to search for: + +<!-- The name of the form must be "f" (used in "quicksearch.js"). --> + +<form name="f" action="show_bug.cgi" method="get" + onsubmit="QuickSearch(); 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> +<!-- +document.forms['f'].id.focus(); +//--> +</script> + +<p> +<h2>Getting Started</h2> + +<ul> +<li> This is <b>case-insensitive</b> search. + <ul> + <li> <tt>table</tt> , <tt>Table</tt> + and <tt>TABLE</tt> are all the same. + </ul> +<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> Use <tt>bookmark</tt> instead of <tt>bookmarks</tt> or + <tt>bookmarking</tt>. + </ul> +</ul> + +<a name="features"/> +<h2>Features</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 <tt><b>-</b><i>foo</i></tt> to exclude bugs + with <tt><i>foo</i></tt> in the summary. + <li> <b>AND</b>: Space-separated words are treated as a conjunction. + <li> <b>OR</b>: Within a word, "|"-separated parts denote alternatives. + <li> Besides "|", a comma can be used to separate alternatives. + <li> OR has higher precedence than AND; AND is the top level operation + </ul> + <i>Example:</i> <tt>url,location bar,field -focus</tt> + means + <nobr>(<tt>url</tt> OR <tt>location</tt>) AND (<tt>bar</tt> OR <tt>field</tt>) AND (NOT <tt>focus</tt>)</nobr> + <p> +<li> Use <tt>+foo</tt> to search for bugs where the <b>summary</b> contains <tt>foo</tt> as a <b>substring</b>.<br> + Use <tt>#foo</tt> to search for bugs where the <b>summary</b> contains the <b>word</b> <tt>foo</tt> + <ul> + <li> <tt>+brow</tt> does not find all bugs in the <tt>Browser</tt> product + <li> <tt>#title</tt> does not find bugs bugs with <tt>titlebar</tt> or <tt>titled</tt> + </ul> + Phrases with special chars (space, comma, +, -, #, ...) can be <b>quoted</b>: + <ul> + <li> <tt>"lock icon"</tt> + </ul> +<p> +<li> <b>Open vs. Resolved Bugs</b>:<br> + By default, only open (i.e. unresolved) bugs are shown. + Use <tt>+DUP</tt> as first word in your query + to include duplicate bugs in your search, + <tt>FIXED</tt> to search for fixed bugs only, + or <tt>ALL</tt> 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> <tt>+DUP,FIXED table border</tt> + <li> <tt>ALL mouse wheel</tt> + </ul> +<p> +<li> <b>Focus the Search with Products & Components</b>:<br> + To search for bugs in product "Foo Bar" only, add + <tt>:foo</tt> or <tt>:bar</tt> 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. +</ul> + +<h2>More Tips</h2> + +<ul> +<li> You can also use this tool to <b>lookup</b> a bug by its number. + <ul> + <li> <tt>12345</tt> + </ul> +<li> A comma-separated list of bug numbers gives you a list of these bugs. + <ul> + <li> <tt>12345,23456,34567</tt> + </ul> +</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> + +Use the powerful +<a href="query.cgi">Bugzilla Query Form</a> +for advanced queries. + +</body> +</html> + + + + + diff --git a/quicksearch.js b/quicksearch.js new file mode 100644 index 000000000..e14710c9a --- /dev/null +++ b/quicksearch.js @@ -0,0 +1,670 @@ +// +// 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> + +function go_to (url) { + document.location.href = url; + //window.open(url, "other" ); +} + +function map(l, f) { + 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) { + return (l.length > 0) + && ((s == l[0]) || member(s, l.slice(1))); +} + +function add(s, l) { + if (! member(s, l)) { + l.unshift(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 undefined; +} + +// `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) { + s = str.toLowerCase(); + return (s.length > 2) && (! member(s,product_exceptions)); +} + +// `component_exceptions are defined externally + +function match_component(str) { + 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 = ""; + + var searchURL = url; //bugzilla + "buglist.cgi"; + var abort = false; + + // escape everything between quotes: "foo bar" --> "foo%20bar" + var parts = input.split('"'); + if ((parts.length % 2) != 1) { + alert('Unterminated quote'); + abort = true; + return undefined; + } + for (var i=1; i<parts.length; i+=2) { + parts[i] = escape(parts[i]); + } + var 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 undefined; + } + + // 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 + var word = input2.split(/[\s]+/); + + // determine bug_status and resolution + // the first word may contain relevant info + + // `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(); + + // 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 iff 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); + word.shift(); + } else if (word[0] == "OPEN") { + // special case: search for open bugs only + word.shift(); + } else if (word[0].match("^[+][A-Z]+(,[A-Z]+)*$")) { + // e.g. +DUP,FIX + w0 = word.shift(); + prefixes = w0.substring(1).split(","); + if (! matchPrefixes(prefixes,statusResolved,resolutions)) { + word.unshift(w0); + } + } else if (word[0].match("^[A-Z]+(,[A-Z]+)*$")) { + // e.g. NEW,ASSI,REOP,FIX + bug_status = new Array(); // reset + w0 = word.shift(); + prefixes = w0.split(","); + if (! matchPrefixes(prefixes,statusAll,resolutions)) { + word.unshift(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(); + resolution.unshift("---"); + 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 + + var chart = 0; + var and = 0; + var or = 0; + + var 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; + } + } + + 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 (var i=0; i<word.length; i++, chart++) { + + w = word[i]; + + negation = false; + if (w[0] == "-") { + negation = true; + w = w.substring(1); + } + + switch (w[0]) { + case "+": + alternative = w.substring(1).split(/[|,]/); + for (var 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 ( var 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 ( var 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 (var 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("^[^:]+[:][^:\/][^:]*$")) { + parts = w.split(":"); + fields = parts[0].split(/[,]+/); + values = parts[1].split(/[,]+/); + for (var k=0; k<fields.length; k++) { + field = mapField(fields[k]); + if (field == undefined) { + alert("`"+fields[k]+"'"+ + " is not a valid field name."); + abort = true; + return undefined; + } else { + for (var l=0; l<values.length; l++) { + add_chart(field,"substring",values[l]); + } + } + } + continue; + } + comma_separated_words=w.split(/[,]+/); + for (var 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); + } + } + } + + or = 0; + } + + //searchURL += "&cmdtype=doit"; + + if (abort == false) { + return searchURL; + } else { + return undefined; + } +} + +function unique_id () { + return (new Date()).getTime(); +} + +function ShowURL(mode) { + var input = document.f.id.value; + var searchURL = make_query_URL(bugzilla+"buglist.cgi", input, false); + if (searchURL != undefined) { + 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 != undefined) { + 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. It's name must be document.f.id . +// +// 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 () +{ + var input = document.f.id.value; + + 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() { + var input = document.f.id.value; + Search(bugzilla+"query.cgi",input,false); + return; +} + diff --git a/quicksearchhack.html b/quicksearchhack.html new file mode 100644 index 000000000..f8c15bc5e --- /dev/null +++ b/quicksearchhack.html @@ -0,0 +1,350 @@ +<html> +<head> + <title>Bugzilla QuickSearch (for Hackers)</title> +</head> + +<body bgcolor="#ffffff"> + +<script src="localconfig.js"></script> +<script src="quicksearch.js"></script> + +<h1>Bugzilla QuickSearch (for Hackers)</h1> + +Type in one or more words (or word fragments) to search for: + +<!-- The name of the form must be "f" (used in "quicksearch.js"). --> + +<form name="f" action="show_bug.cgi" method="get" + onsubmit="QuickSearch(); 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();" /> + </td> + </tr> + </table> +</form> + +<script> +<!-- +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 you enter only a single +word, the URL field is included in the search, too. +<p> +The generic format for a ``word'' is + <tt>field1,...,fieldN:value1,...,valueM</tt> . +A bug qualifies if at least one of the values occurs as a substring in +at least one of the fields. +For example, <tt>owner,reporter,qa:ibm,sun</tt> +will give you bugs where the owner, reporter, or qa contact +has an email address that contains + <tt>ibm</tt> or <tt>sun</tt> . +If only <tt>value1,...,valueM</tt> is given, +the prefix (roughly) defaults to <tt>summary,keywords,product,component,statuswhiteboard:</tt> as noted above. +<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> </td> + <td rowspan=2><tt><nobr>UNCO,NEW,...,CLOS,</nobr><br><nobr>FIX,DUP,...</nobr> <i><nobr>(as first word)</nobr></i></tt></td> + <td><tt>status</tt></td> + <td> </td> + <td><a href="bug_status.html">Status</a> + <i>("bug_status")</i> + </td> +</tr> +<tr> + <td> </td> + <td><tt>resolution</tt></td> + <td> </td> + <td><a href="bug_status.html">Resolution</a></td> +</tr> +<tr> + <td> </td> + <td><i>as-is</i></td> + <td><tt>platform</tt></td> + <td> </td> + <td><a href="bug_status.html#rep_platform">Platform</a> <i>("rep_platform")</i></td> +</tr> +<tr> + <td> </td> + <td> </td> + <td><tt>os</tt></td> + <td><tt>opsys</tt></td> + <td><a href="bug_status.html#op_sys">OS</a> <i>("op_sys")</i></td> +</tr> +<tr> + <td> </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="bug_status.html#priority">Priority</a></td> +</tr> +<tr> + <td> </td> + <td><tt>blo,cri,...,enh</tt></td> + <td><tt>severity</tt></td> + <td><tt>sev</tt></td> + <td><a href="bug_status.html#severity">Severity</a> <i>("bug_severity")</i></td> +</tr> + +<!-- People: AssignedTo, Reporter, QA Contact, CC, Added comment --> +<!-- Added comment is missing!!!! --> + +<tr> + <td> </td> + <td><b>@</b><i>owner</i></td> + <td><tt>assignedto</tt></td> + <td><tt>assignee, owner</tt></td> + <td><a href="bug_status.html#assigned_to">Assignee</a> <i>("assigned_to")</i></td> +</tr> +<tr> + <td> </td> + <td> </td> + <td><tt>reporter</tt></td> + <td><tt>rep</tt></td> + <td>Reporter (email)</td> +</tr> +<tr> + <td> </td> + <td> </td> + <td><tt>qa</tt></td> + <td><tt>qacontact</tt></td> + <td>QA Contact (email) <i>("qa_contact")</i></td> +</tr> +<tr> + <td> </td> + <td> </td> + <td><tt>cc</tt></td> + <td> </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> </td> + <td> </td> + <td><tt>version</tt></td> + <td><tt>ver</tt></td> + <td>Version (enum)</td> +</tr> +<tr> + <td> </td> + <td> </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> </td> + <td><tt>summary</tt></td> + <td><tt>shortdesc</tt></td> + <td>Bug Summary (short text)<i>("short_desc")</i></td> +</tr> +<tr> + <td> </td> + <td> </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>one-word queries only</i></td> + <td> </td> + <td><tt>url</tt></td> + <td> </td> + <td>URL <i>("bug_file_loc")</i></td> +</tr> +<tr> + <td><i>yes</i></td> + <td> </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> </td> + <td> </td> + <td><tt>attachmentdesc</tt></td> + <td><tt>attachdesc</tt></td> + <td>Attachment Description <i>("attachments.description")</i></td> +</tr> +<tr> + <td> </td> + <td> </td> + <td><tt>attachmentdata</tt></td> + <td><tt>attachdata</tt></td> + <td>Attachment Data <i>("attachments.thedata")</i></td> +</tr> +<tr> + <td> </td> + <td> </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</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</td> +</tr> +<tr> + <td><b>@</b><i>owner</i></td> + <td><b>assignedto:</b><i>owner</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">"Features"</a> section +on the <a href="quicksearch.html">introductory page</a>. + +</body> +</html> + |