2001-03-01 02:07:26 +03:00
|
|
|
//
|
|
|
|
// 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>
|
2001-05-29 07:05:46 +04:00
|
|
|
//
|
|
|
|
// Contributors:
|
|
|
|
// Stephen Lee <slee@uk.bnsmc.com>
|
|
|
|
|
|
|
|
|
2001-07-20 12:25:30 +04:00
|
|
|
// Use no_result variable to avoid problems with "undefined" on some browsers
|
2001-05-29 07:05:46 +04:00
|
|
|
|
2001-07-20 12:25:30 +04:00
|
|
|
var no_result="---";
|
2001-05-29 07:05:46 +04:00
|
|
|
|
2001-07-20 12:25:30 +04:00
|
|
|
// do_unshift(l, s) is equivalent to l.unshift(s), but some browsers do not
|
|
|
|
// support the built-in function.
|
2001-05-29 07:05:46 +04:00
|
|
|
|
|
|
|
function do_unshift(l, s) {
|
2001-07-20 12:25:30 +04:00
|
|
|
l.length = l.length + 1;
|
|
|
|
for (var i=l.length-1; i>0; i--) {
|
|
|
|
l[i] = l[i-1];
|
2001-05-29 07:05:46 +04:00
|
|
|
}
|
2001-07-20 12:25:30 +04:00
|
|
|
l[0] = s;
|
|
|
|
return l.length;
|
2001-05-29 07:05:46 +04:00
|
|
|
}
|
|
|
|
|
2001-07-20 12:25:30 +04:00
|
|
|
// do_shift(l) is equivalent to l.shift(s), but some browsers do not
|
|
|
|
// support the built-in function.
|
|
|
|
|
2001-05-29 07:05:46 +04:00
|
|
|
function do_shift(l) {
|
2001-07-20 12:25:30 +04:00
|
|
|
var l0=l[0];
|
|
|
|
for (var i=0; i<l.length-1; i++) {
|
|
|
|
l[i] = l[i+1];
|
2001-05-29 07:05:46 +04:00
|
|
|
}
|
2001-07-20 12:25:30 +04:00
|
|
|
l.length = l.length - 1;
|
|
|
|
return l0;
|
2001-05-29 07:05:46 +04:00
|
|
|
}
|
2001-03-01 02:07:26 +03:00
|
|
|
|
|
|
|
function go_to (url) {
|
|
|
|
document.location.href = url;
|
|
|
|
//window.open(url, "other" );
|
|
|
|
}
|
|
|
|
|
|
|
|
function map(l, f) {
|
2001-05-29 07:05:46 +04:00
|
|
|
var l1 = new Array();
|
2001-03-01 02:07:26 +03:00
|
|
|
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) {
|
2001-06-16 00:16:59 +04:00
|
|
|
for (var i=0; i<l.length; i++) {
|
|
|
|
if (l[i] == s) return true;
|
|
|
|
}
|
|
|
|
return false;
|
2001-03-01 02:07:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function add(s, l) {
|
|
|
|
if (! member(s, l)) {
|
2001-05-29 07:05:46 +04:00
|
|
|
do_unshift(l,s);
|
2001-03-01 02:07:26 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
2001-05-29 07:05:46 +04:00
|
|
|
return no_result;
|
2001-03-01 02:07:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// `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) {
|
2001-05-29 07:05:46 +04:00
|
|
|
var s = str.toLowerCase();
|
2001-03-01 02:07:26 +03:00
|
|
|
return (s.length > 2) && (! member(s,product_exceptions));
|
|
|
|
}
|
|
|
|
|
|
|
|
// `component_exceptions are defined externally
|
|
|
|
|
|
|
|
function match_component(str) {
|
2001-05-29 07:05:46 +04:00
|
|
|
var s = str.toLowerCase();
|
2001-03-01 02:07:26 +03:00
|
|
|
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 = "";
|
|
|
|
|
2001-05-29 07:05:46 +04:00
|
|
|
// 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();
|
2001-03-01 02:07:26 +03:00
|
|
|
|
|
|
|
// escape everything between quotes: "foo bar" --> "foo%20bar"
|
2001-05-29 07:05:46 +04:00
|
|
|
parts = input.split('"');
|
2001-03-01 02:07:26 +03:00
|
|
|
if ((parts.length % 2) != 1) {
|
|
|
|
alert('Unterminated quote');
|
|
|
|
abort = true;
|
2001-05-29 07:05:46 +04:00
|
|
|
return no_result;
|
2001-03-01 02:07:26 +03:00
|
|
|
}
|
2001-05-29 07:05:46 +04:00
|
|
|
for (i=1; i<parts.length; i+=2) {
|
2001-03-01 02:07:26 +03:00
|
|
|
parts[i] = escape(parts[i]);
|
|
|
|
}
|
2001-05-29 07:05:46 +04:00
|
|
|
input2 = parts.join('"');
|
2001-03-01 02:07:26 +03:00
|
|
|
|
|
|
|
// 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;
|
2001-05-29 07:05:46 +04:00
|
|
|
return no_result;
|
2001-03-01 02:07:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2001-05-29 07:05:46 +04:00
|
|
|
word = input2.split(/[\s]+/);
|
2001-03-01 02:07:26 +03:00
|
|
|
|
|
|
|
// 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 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);
|
2001-05-29 07:05:46 +04:00
|
|
|
do_shift(word);
|
2001-03-01 02:07:26 +03:00
|
|
|
} else if (word[0] == "OPEN") {
|
|
|
|
// special case: search for open bugs only
|
2001-05-29 07:05:46 +04:00
|
|
|
do_shift(word);
|
2001-03-01 02:07:26 +03:00
|
|
|
} else if (word[0].match("^[+][A-Z]+(,[A-Z]+)*$")) {
|
|
|
|
// e.g. +DUP,FIX
|
2001-05-29 07:05:46 +04:00
|
|
|
w0 = do_shift(word);
|
2001-03-01 02:07:26 +03:00
|
|
|
prefixes = w0.substring(1).split(",");
|
|
|
|
if (! matchPrefixes(prefixes,statusResolved,resolutions)) {
|
2001-05-29 07:05:46 +04:00
|
|
|
do_unshift(word,w0);
|
2001-03-01 02:07:26 +03:00
|
|
|
}
|
|
|
|
} else if (word[0].match("^[A-Z]+(,[A-Z]+)*$")) {
|
|
|
|
// e.g. NEW,ASSI,REOP,FIX
|
|
|
|
bug_status = new Array(); // reset
|
2001-05-29 07:05:46 +04:00
|
|
|
w0 = do_shift(word);
|
2001-03-01 02:07:26 +03:00
|
|
|
prefixes = w0.split(",");
|
|
|
|
if (! matchPrefixes(prefixes,statusAll,resolutions)) {
|
2001-05-29 07:05:46 +04:00
|
|
|
do_unshift(word,w0);
|
2001-03-01 02:07:26 +03:00
|
|
|
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();
|
2001-05-29 07:05:46 +04:00
|
|
|
do_unshift(resolution,"---");
|
2001-03-01 02:07:26 +03:00
|
|
|
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
|
|
|
|
|
2001-05-29 07:05:46 +04:00
|
|
|
chart = 0;
|
|
|
|
and = 0;
|
|
|
|
or = 0;
|
2001-03-01 02:07:26 +03:00
|
|
|
|
2001-05-29 07:05:46 +04:00
|
|
|
negation = false;
|
2001-03-01 02:07:26 +03:00
|
|
|
|
|
|
|
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;
|
2001-05-29 07:05:46 +04:00
|
|
|
return "dummy";
|
2001-03-01 02:07:26 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-05-29 07:05:46 +04:00
|
|
|
for (i=0; i<word.length; i++, chart++) {
|
2001-03-01 02:07:26 +03:00
|
|
|
|
|
|
|
w = word[i];
|
|
|
|
|
|
|
|
negation = false;
|
2001-06-28 20:27:37 +04:00
|
|
|
if (w.charAt(0) == "-") {
|
2001-03-01 02:07:26 +03:00
|
|
|
negation = true;
|
|
|
|
w = w.substring(1);
|
|
|
|
}
|
|
|
|
|
2001-06-28 20:27:37 +04:00
|
|
|
switch (w.charAt(0)) {
|
2001-03-01 02:07:26 +03:00
|
|
|
case "+":
|
|
|
|
alternative = w.substring(1).split(/[|,]/);
|
2001-05-29 07:05:46 +04:00
|
|
|
for (j=0; j<alternative.length; j++)
|
2001-03-01 02:07:26 +03:00
|
|
|
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(",");
|
2001-05-29 07:05:46 +04:00
|
|
|
for (j=0; j<alternative.length; j++) {
|
2001-03-01 02:07:26 +03:00
|
|
|
add_chart("product","substring",alternative[j]);
|
|
|
|
add_chart("component","substring",alternative[j]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "@":
|
|
|
|
alternative = w.substring(1).split(",");
|
2001-05-29 07:05:46 +04:00
|
|
|
for (j=0; j<alternative.length; j++)
|
2001-03-01 02:07:26 +03:00
|
|
|
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("|");
|
2001-05-29 07:05:46 +04:00
|
|
|
for (j=0; j<alternative.length; j++) {
|
2001-03-01 02:07:26 +03:00
|
|
|
|
|
|
|
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("^[^:]+[:][^:\/][^:]*$")) {
|
2001-05-29 07:05:46 +04:00
|
|
|
colon_separated_parts = w.split(":");
|
|
|
|
fields = colon_separated_parts[0].split(/[,]+/);
|
|
|
|
values = colon_separated_parts[1].split(/[,]+/);
|
|
|
|
for (k=0; k<fields.length; k++) {
|
2001-03-01 02:07:26 +03:00
|
|
|
field = mapField(fields[k]);
|
2001-05-29 07:05:46 +04:00
|
|
|
if (field == no_result) {
|
2001-03-01 02:07:26 +03:00
|
|
|
alert("`"+fields[k]+"'"+
|
|
|
|
" is not a valid field name.");
|
|
|
|
abort = true;
|
2001-05-29 07:05:46 +04:00
|
|
|
return no_result;
|
2001-03-01 02:07:26 +03:00
|
|
|
} else {
|
2001-05-29 07:05:46 +04:00
|
|
|
for (l=0; l<values.length; l++) {
|
2001-03-01 02:07:26 +03:00
|
|
|
add_chart(field,"substring",values[l]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
comma_separated_words=w.split(/[,]+/);
|
2001-05-29 07:05:46 +04:00
|
|
|
for (k=0; k<comma_separated_words.length; k++) {
|
2001-03-01 02:07:26 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-03-01 06:34:08 +03:00
|
|
|
and = 0;
|
2001-03-01 02:07:26 +03:00
|
|
|
or = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//searchURL += "&cmdtype=doit";
|
|
|
|
|
|
|
|
if (abort == false) {
|
|
|
|
return searchURL;
|
|
|
|
} else {
|
2001-05-29 07:05:46 +04:00
|
|
|
return no_result;
|
2001-03-01 02:07:26 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2001-05-29 07:05:46 +04:00
|
|
|
if (searchURL != no_result) {
|
2001-03-01 02:07:26 +03:00
|
|
|
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);
|
2001-05-29 07:05:46 +04:00
|
|
|
if (searchURL != no_result) {
|
2001-03-01 02:07:26 +03:00
|
|
|
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;
|
|
|
|
|
2001-06-18 23:24:17 +04:00
|
|
|
//remove leading and trailing whitespace
|
|
|
|
input = input.replace(/^[\s]+/,"").replace(/[\s]+$/,"");
|
|
|
|
|
2001-03-01 02:07:26 +03:00
|
|
|
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;
|
2001-06-18 23:24:17 +04:00
|
|
|
|
|
|
|
//remove leading and trailing whitespace
|
|
|
|
input = input.replace(/^[\s]+/,"").replace(/[\s]+$/,"");
|
|
|
|
|
2001-03-01 02:07:26 +03:00
|
|
|
Search(bugzilla+"query.cgi",input,false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|