From 65db58735021ec41ea90316165de47f2d6f55ffe Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Sun, 15 Nov 2009 23:35:25 +0100 Subject: Initial commit for development of a Jetpack package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit committer: Matěj Cepl --- bugzillaBugTriage.user.js | 1301 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1301 insertions(+) create mode 100644 bugzillaBugTriage.user.js (limited to 'bugzillaBugTriage.user.js') diff --git a/bugzillaBugTriage.user.js b/bugzillaBugTriage.user.js new file mode 100644 index 0000000..eed156c --- /dev/null +++ b/bugzillaBugTriage.user.js @@ -0,0 +1,1301 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php +// +// ==UserScript== +// @name Bugzilla modifications for bug triage +// @namespace http://www.ceplovi.cz/matej/progs/scripts +// @description buttons and other modifications of Bugzilla for bug triage +// @version 0.2 +// @include https://bugzilla.redhat.com/show_bug.cgi* +// @include https://bugzilla.redhat.com/process_bug.cgi +// @require http://mcepl.fedorapeople.org/scripts/xmlrpc.js +// ==/UserScript== + +// https://bugzilla.redhat.com/show_bug.cgi?id=451951 +// + +/* ***************************************************** +NOTES: +jetpack.future.import("pageMods"); +function callback (document) { +// something +}; +var options = {}; +options.matches = ["http://*.reddit.com/*","blabla"]; +jetpack.pageMods.add(callback, options); + +point of jetpack.pageMods is not to modify the page (you can do +it just by jQuery), but this script will be run on every page, +and this filters out those which are uninteresting. +*******************************************************/ + + +// ************* FUNCTIONS ******************** +/* EXTERNAL FUNCTIONS */ +/** + * split URI into array + * + * @param str string with the URL + * @return array with parsed URL + * + * parseUri 1.2.1 + * originally from http://blog.stevenlevithan.com/archives/parseuri + * (c) 2007 Steven Levithan + * MIT License + */ +function parseUri (str) { + var o = parseUri.options, + m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), + uri = {}, + i = 14; + + while (i--) { + uri[o.key[i]] = m[i] || ""; + } + + uri[o.q.name] = {}; + uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { + if ($1) uri[o.q.name][$1] = $2; + }); + + return uri; +}; + +parseUri.options = { + strictMode: false, + key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], + q: { + name: "queryKey", + parser: /(?:^|&)([^&=]*)=?([^&]*)/g + }, + parser: { + strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, + loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ + } +}; + +/** + * Clean the string from spaces around + * + * @param string to be cleaned + * @return string which was cleaned + * + */ +function strip(str) { + return str.replace(/^\s*(.*)\s*$/,"$1"); +} + +/** + * Primitive version of sprintf + * @param string with the format of the result and + * @param list of parameters + * @return string with the format applied + * + * Call as + * format("And the %1 want to know whose %2 you %3", "papers", "shirt", "wear"); + * originally from + * http://www.sitepoint.com/blogs/2008/11/11/arguments-a-javascript-oddity/ + * FIXME needs testing and debugging + */ +function format(string) { + var args = arguments; + var pattern = new RegExp("%([1-" + arguments.length + "])", "g"); + return String(string).replace(pattern, function(match, index) { + return args[index]; + }); +} + +/** + * escape input string so that it could be used in URLs + * @param clearString + * @return string decoded so that it is safe for URLs + */ +function URLEncode (clearString) { + var output = ''; + var x = 0; + clearString = clearString.toString(); + var regex = /(^[a-zA-Z0-9_.]*)/; + while (x < clearString.length) { + var match = regex.exec(clearString.substr(x)); + if (match != null && match.length > 1 && match[1] != '') { + output += match[1]; + x += match[1].length; + } else { + if (clearString[x] == ' ') + output += '+'; + else { + var charCode = clearString.charCodeAt(x); + var hexVal = charCode.toString(16); + output += '%' + ( hexVal.length < 2 ? '0' : '' ) + hexVal.toUpperCase(); + } + x++; + } + } var output = ''; + var x = 0; + clearString = clearString.toString(); + var regex = /(^[a-zA-Z0-9_.]*)/; + while (x < clearString.length) { + var match = regex.exec(clearString.substr(x)); + if (match != null && match.length > 1 && match[1] != '') { + output += match[1]; + x += match[1].length; + } else { + if (clearString[x] == ' ') + output += '+'; + else { + var charCode = clearString.charCodeAt(x); + var hexVal = charCode.toString(16); + output += '%' + ( hexVal.length < 2 ? '0' : '' ) + hexVal.toUpperCase(); + } + x++; + } + } + return output; + + return output; +} + +/** + * select element of the array where regexp in the first element matches second parameter + * of this function + * @param list array with regexps and return values + * @param chosingMark string by which the element of array is to be matched + * @return string chosen element + */ +function filterByRegexp(list,chosingMark) { + var chosenPair = Array(); + if (list.length > 0) { + chosenPair = list.filter( + function(pair){ + return RegExp(pair['regexp']).test(chosingMark); + }); + }; + if (chosenPair.length > 0) { + return strip(chosenPair[0]['addr']).toLowerCase(); + } else { + return ""; + } +} + +/** + * Converts attributes value of the given list of elements to the + * Javascript list. + * @param list array of elements + * @return array of values + */ +function valuesToList(list) { + var outL = []; + var member = ""; + + for (var i = 0; i < list.length; i++) { + // FIXME how to say hasAttribute in jQuery? + if(list[i].hasAttribute("value")) { + // FIXME getAttribute in jQuery + member = list[i].getAttribute("value"); + member = member.replace(/\s*(.*)\s*/,"$1"); + outL[outL.length] = member; + } + } + return outL; +} + +/** + * Check whether an item is member of the list. Idea is just to + * make long if commands slightly more readable. + * + * @param mbr string to be searched in the list + * @param list list + * @return position of the string in the list, or -1 if none found. + */ +function isInList(mbr,list) { + return(list.indexOf(mbr) !== -1); +} + +/** + * returns content of the system clipboard + * @return string with the content of the clipboard or "" if empty. + * originally from + * https://developer.mozilla.org/en/Using_the_Clipboard + * + */ +// FIXME to-be-replaced by +// var contents = jetpack.clipboard.get(); +unsafeWindow.getClipboard = function() { + this.netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); + + var clip = Components.classes["@mozilla.org/widget/clipboard;1"].getService(Components.interfaces.nsIClipboard); + if (!clip) return false; + + var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable); + if (!trans) return false; + trans.addDataFlavor("text/unicode"); + + clip.getData(trans, clip.kGlobalClipboard); + + var str = new Object(); + var strLength = new Object(); + + trans.getTransferData("text/unicode", str, strLength); + + if (str) + str = str.value.QueryInterface(Components.interfaces.nsISupportsString); + if (str) + pastetext = str.data.substring(0, strLength.value / 2); + + return pastetext; +}; + + function getClipboardText() { + return unsafeWindow.getClipboard(); + } + +/** + * Compatibility layer for Firefox <3.1 which doesn't have native JSON support + * + * @param str string with the JSON data + * @return object + */ +//FIXME get rid of this ... user just has to have FF > 3.1 +function jsonParse(str) { + if (JSON) { + return JSON.parse(str); + } else { + return(eval('(' + str + ')')); + } +} + +/* Bugzilla functions.*/ + +/** + * add Fedora Bug zapper's signature to the comment of the current bug + */ +function addSignature(evt) { + var cmntText = document.getElementById("comment"); + if ((signatureFedoraString.length > 0) && (strip(cmntText.value).length > 0)) { + cmntText.value = strip(cmntText.value) + signatureFedoraString; + } +} + +/** + * Send mouse click to the specified element + * @param element where to send mouseclick to + * @return None + */ +function clickMouse(target) { + var localEvent = document.createEvent("MouseEvents"); + localEvent.initMouseEvent("click", true, true, window, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + target.dispatchEvent(localEvent); +} + +// ****************************************** + +/** + * Parse the row with the attachment + * @param element to be parsed + * @return array with string name of the attachment, + integer its id number, + string of MIME type, + integer of size in kilobytes, + and the whole element itself + */ +function parseAttachmentLine(inElem) { + var name = String(); + var MIMEtype = String(); + var size = Number(); + var id = Number(); + + inElem.normalize(); + + // getting name of the attachment + var bElem = inElem.getElementsByTagName("b")[0]; + name = strip(bElem.textContent); + + // getting id + var aElem = inElem.getElementsByTagName("a")[0]; + id = parseInt(aElem.getAttribute("href").replace(/^.*attachment.cgi\?id=/,""),10); + + //getting MIME type and size + // not sure whether the following is possible, otherwise + // I would have to get first span element + var spanElems = inElem.getElementsByClassName("bz_attach_extra_info")[0]; + var roundedText = spanElems.innerHTML; + + var stringArray = strip(roundedText.replace(/^\s*\((.*)\s*KB,\s*$/,"$1")); + size = parseInt(stringArray,10); + MIMEtype = roundedText.split("\n")[2].replace(/^\s*(.*)\)\s*$/,"$1"); + + return([name,id,MIMEtype,size,inElem]); +} + +/** + * Get the attachments table of the bug + * + * @return attachments table + */ +function getAttTable() { + var tempList = document.getElementById("attachment_table"); + return(tempList); +} + +/** + * Get list of attachments to the bug + * + * @return array of attachments + */ +function getAttachments(attTable) { + var attList = Array(); + + var tempT = attTable.getElementsByTagName("tr"); + if (tempT.length > 2) { + for (var i=1;i element with given id. + * + * Also execute change HTMLEvent, so that the form behaves accordingly. + * + * @param id + * @param label + * @return none + */ +function selectOption(id,label) { + var selectElement = document.getElementById(id); + var values = selectElement.options; + for (var i = 0; i < values.length; i++) { + values[i].normalize(); + if (values[i].text.search(label) != -1) { + values[i].selected = true; + var intEvent = document.createEvent("HTMLEvents"); + intEvent.initEvent("change", true, true); + selectElement.dispatchEvent(intEvent); + break; + } + } +} + +/** + * Returns the component of the bug + * + * @return string component of the bug + */ +function getComponent() { + return strip(document.getElementById("component").value); +} + +/** + * Returns the product the bug belongs to + * + * @return string product the bug belongs to + */ +function getProduct() { + var productSelect = document.getElementById("product"); + var index = productSelect.selectedIndex; + return productSelect.options[index].value; +} + +/** + * Returns the version of product the bug belongs to + * + * @return string revision of the product the bug belongs to + */ +function getVersion() { + var versionSelect = document.getElementById("version"); + if (versionSelect) { + var index = versionSelect.selectedIndex; + return versionSelect.options[index].value; + } else { + return null; + } +} + +/** + * Returns owner of the bug. + * + * @return string with the email address of the assignee. + */ +function getAssignedTo() { + var assigneeEditContainer = document.getElementById("bz_assignee_edit_container").getElementsByClassName("fn")[0]; + return strip(assigneeEditContainer.textContent).toLowerCase(); +} + +/** + * Returns reporter of the bug. + * + * @return string with the email address of the reporter. + */ +function getReporter() { + var reportedSpanTag = document.getElementById("bz_show_bug_column_2").getElementsByClassName("fn")[0]; + return reportedSpanTag.textContent; +} + +/** + * Returns the number of the current bug + * + * @return int with the bug number + */ +function getBugNo() { + var title = strip(document.getElementById("title").getElementsByTagName("p")[0].innerHTML); + var bugNo = eval(title.split(" ")[1]); + return bugNo; +} + +/** + * Returns list of people getting CC of all bug messages. + * + * @return array with the all members of the CC list. + */ +function getCCList() { + var selectRef = document.getElementsByName("cc"); + if (selectRef.length>0) { + return valuesToList(selectRef[0]); + } else { + return []; + } +} + +/** + * Returns an email address for collective maintainers + * who should be on the CC of the bug. + * + * @return string email address to be on CC list. + */ +function getCCMaintainer() { + return filterByRegexp(AddrArray,component); +} + +/** + * Returns default assignee for the bug's component + * @return string with the default assignee for given component + */ +function getDefaultAssignee() { + return filterByRegexp(defAssigneeList,getComponent()); +} + +/** + * Get Issuetracker string from the bug page + * @return string issuetracker numbers or empty string (either because we have no IT + * or because it is not a RHEL bug). + */ +function getIssueTracker() { + var interestingElement = document.getElementById("cf_issuetracker"); + if (interestingElement) { + return strip(interestingElement.value); + } else { + return ""; + } +} + + +/** + * Add accesskey to the particular element + * + * @param rootElement element to which the new text object will be attached + * @param beforeText text before the accesskey character + * @param accKey what will be the accesskey itself + * @param afterText text after the accesskey character + * @return modified element with the fixed accesskey + * +*/ +function fixElement(rootElement,beforeText,accKey,afterText) { + rootElement.setAttribute("accesskey",accKey.toLowerCase()); + rootElement.innerHTML = beforeText + "" + accKey + "" + afterText; + return rootElement; +} + +/** + * Set branding colours to easily distinguish between Fedora and RHEL bugs + * @param brand string with product of the current bug + * @param version string with the version of the bug + * @param its string with the IsueTracker numbers + * @return + */ +function setBranding(brand,version,its) { + var brandColor = ""; + + if (brand.search(/Red Hat Enterprise Linux/) != -1) { + if (its.length > 0) { + brandColor = RHITColor; + } else { + brandColor = RHColor; + } + } else if (brand.search(/Fedora/) != -1) { + if (version.search(/rawhide/i) != -1) { + brandColor = RawhideColor; + } else { + brandColor = FedoraColor; + } + } + + // Comment each of the following lines to get only partial branding + document.body.style.background = brandColor; + document.getElementById("titles").style.background = brandColor; + + // Make background-color of the body of bug salmon pink + // for security bugs. + if (hasKeyword("Security")) { + var divBody = document.getElementById("bugzilla-body"); + divBody.style.backgroundImage = "none"; + divBody.style.backgroundColor = SalmonPink; + } + + + // we should make visible whether maintCCAddr is in CCList + if (isInList(maintCCAddr, CCList)) { + var switchCCEdit=document.getElementById("cc_edit_area_showhide"); + //switchCCEdit.textContent = "*"+switchCCEdit.textContent; + switchCCEdit.style.color = "navy"; + switchCCEdit.style.fontWeight = "bolder"; + switchCCEdit.style.textDecoration = "underline"; + } + +} + +/** + * Generic function to add new button to the page. + * Actually copies new button from the old one (in order to have the same + * look-and-feel, etc. + * @param originalLocation object with the button to be copied from + * @param newId string with the id of the new button; has to be unique in + whole page + * @param newLabel string with the label which will be shown to user + * @param commentString string with comment to be added to the comment box + * @param nState string with the new state bug should switch to (see + * generalPurposeCureForAllDisease function for details) + * @param secPar string with second parameter for generalPurposeForAllDisease + * @param doSubmit bool optional whether the button should submit whole page + * (default true) + * + * @return none + */ +function addNewButton(originalLocation,newId,newLabel,commentString,nState,secPar,doSubmit) { + if (doSubmit === null) { // missing optional argument + doSubmit = true; + } + var newButton = originalButton.cloneNode(true); + if (!doSubmit) { + newButton.setAttribute("type","button"); + } + newButton.id=newId; + newButton.setAttribute("value",newLabel); + var commStr = ""; + if (msgStrs[commentString]) { + commStr = msgStrs[commentString]; + } + newButton.addEventListener('click',function (evt) { + generalPurposeCureForAllDisease(commStr, nState, secPar); + },true); + var textNode = document.createTextNode("\u00A0"); + originalLocation.parentNode.insertBefore(textNode,originalLocation); + originalLocation.parentNode.insertBefore(newButton,textNode); +} + +/** + * Add new keyword among the keywords. + * + * @param str string with the new keyword + * @return none + * + * Checks for the existing keywords. + */ +function addKeyword(str) { + var kwd = document.getElementById('keywords'); + if (kwd.value.length == 0) { + kwd.value = str; + }else{ + kwd.value = kwd.value + ", " + str; + } +} + +/** + * Check for the presence of a keyword + * + * @param str string with the keyword + * @return Boolean + * + */ +function hasKeyword(str) { + var kwd = strip(document.getElementById('keywords').value); + return (RegExp(str).test(kwd)); +} + + +/** + * Add XGL to the CC list + * + * @param evt event which made this function active + * @return none + */ +function changeOwnerHandler(evt) { + /** Take care that when changing assignment of the bug, + * current owner is added to CC list. + * Switch off setting to the default assignee + */ + if (!isInList(maintCCAddr, CCList)) { + addToCC(maintCCAddr); + } + var setDefaultAssigneeCheckbox = document.getElementById("set_default_assignee"); + setDefaultAssigneeCheckbox.checked = false; + selectOption("bug_status", "ASSIGNED"); +} + +/** + * Set the bug to NEEDINFO state + * + * Working function. + * @return none + */ +function setNeedinfoReporter() { + var checkbox = document.getElementById("needinfo"); + checkbox.click(); + selectOption("needinfo_role", "reporter"); +} + +/** + * Add text to the comment. + * @param string2BAdded string to be added to the comment box + * + * @return none + */ +function addTextToComment(string2BAdded) { + var commentTextarea = document.getElementById("comment"); + + // don't remove the current content of the comment box, + // just behave accordingly + if (commentTextarea.value.length > 0) { + commentTextarea.value += "\n\n"; + } + commentTextarea.value += string2BAdded; +} + +/** + * add address to CC of this bug + * + * @param address string address to be added + * @return none + */ +function addToCC(address) { + var sel = document.getElementById("newcc"); + sel.value = address; +} + +/** + * Generalized function for all actions + * + * @param addString string to be added as new comment + * @param nextState string signifying next state of the bug (whatever is in Bugzilla + + "NEEDINFO" meaning NEEDINFO(Reporter)) + * @param secondParameter string with label on the subbutton for reason + * of closing the bug + * @return none + */ +function generalPurposeCureForAllDisease(addString,nextState,secondParameter) { + if (addString.length >0) { + addTextToComment(addString); + } + + if (nextState == "CLOSED") { + if (secondParameter == "UPSTREAM") { + addClosingUpstream(); + } else if (secondParameter.length > 0) { + selectOption("bug_status", nextState); + selectOption("resolution",secondParameter); + return 0; + } else { + throw("Missing resolution for CLOSED status."); + } + } + + // Now closing bugs is done, what about the rest? + if (nextState == "NEEDINFO") { + setNeedinfoReporter(); + } else if (nextState == "ADDKEYWORD") { + if (secondParameter.length == 0) { + throw "Keyword has to be defined"; + } + addKeyword(secondParameter); + } else if (nextState == "ASSIGNED") { + if (!isInList(maintCCAddr, CCList)) { + addToCC(maintCCAddr); + } + selectOption("bug_status", nextState); + } else if (nextState.length >0) { + selectOption("bug_status", nextState); + } + + if (secondParameter == "ADDSELFCC") { + document.getElementById("addselfcc").checked = true; + } else if (secondParameter == "NODEFAULTASSIGNEE") { + document.getElementById("set_default_assignee").checked = false; + } +} + +/** + * Return string with the ID for the external_id SELECT for + * external bugzilla + * + * @param URLhostname string hostname of the external bugzilla + * @return string with the string for the external_id SELECT + */ +function getBugzillaName(URLhostname) { + var bugzillaID = ""; + if (hashBugzillaName[URLhostname]) { + bugzillaID = hashBugzillaName[URLhostname]; + } else { + bugzillaID = ""; + } + return bugzillaID; +} + +/** + * Generate URL of the bug on remote bugzilla + * @param selectValue Number which is index of the bugzilla in hashBugzillaWholeURL + * @param bugID Number which is bug ID + * @return string with the URL + */ +function getWholeURL(selectValue,bugID) { + var returnURL = ""; + if (hashBugzillaWholeURL[selectValue]) { + returnURL = hashBugzillaWholeURL[selectValue]+bugID; + } else { + returnURL = ""; + } + return returnURL; +} + +/** + * Add information about the upstream bug upstream, and closing it. + * @param evt event which called this handler + * + * @return none + */ +function addClosingUpstream() { + var externalRefs = document.getElementById("external_bugs_table"); + var refs = externalRefs.getElementsByTagName("tr"); + // that's a bad id, if there is a one. + var inputBox = document.getElementById("inputbox"); + var externalBugID = 0; + var externalHost = ""; + var wholeURL = ""; + + // Fix missing ID on the external_id SELECT + document.getElementsByName("external_id")[0].id = "external_id"; + + if (inputBox.value.match(/^http.*/)) { + wholeURL = inputBox.value; + var IBURLArr = parseUri(wholeURL); + externalHost = IBURLArr.host; + externalBugID = parseInt(IBURLArr.queryKey["id"]); + inputBox.value = externalBugID; + var bugzillaName = getBugzillaName(externalHost); + selectOption("external_id", bugzillaName); + } else if (!isNaN(inputBox.value)) { + externalBugID = parseInt(inputBox.value); + var bugzillaID = document.getElementById("external_id").value; + wholeURL = getWholeURL(bugzillaID,externalBugID); + } else { + // no inputBox.value -- maybe there is an external bug from + // the previous commit? + ; + } + + // It is not good to close bug as UPSTREAM, if there is no reference + // to the upstream bug. + if ((refs.length > 2) || (externalBugID > 0)) { + addTextToComment(msgStrs['sentUpstreamString'].replace("§§§",wholeURL)); + selectOption("bug_status", "CLOSED"); + selectOption("resolution", "UPSTREAM"); + } else { + alert("No external bug specified among the External References!"); + } +} + +/** + * Currently we don't use this function + * @param evt event send from DOM (not used) + * @return none + */ +function swapXGLMainToCCListHandler(evt) { + /** Remove mcepl@redhat.com from CC list and put there + * xgl-maint@redhat.com + */ + + myAddrIndex = CCList.indexOf(login); + if (!isInList(maintCCAddr, CCList)) { + addToCC(maintCCAddr); + } + if (isInList(login, CCList)) { + var selBox = document.getElementById("cc"); + selBox[myAddrIndex].selected = true; + document.getElementById("removecc").checked = true; + } + evt.stopPropagation(); + evt.preventDefault(); +} + +/** + * Go through all <a> elements in the page and fix those starting with # + * to point to the real bug, not to process.cgi page. + * @param bugNo + */ +function fixAllHrefs(bugNo) { + var AList = document.getElementsByTagName("a"); + var curA; + var hrefStr = ""; + var reProcess = RegExp(""); + + for(var i=0;i elements in the page + var IBList = []; + var IBRawList = document.getElementsByTagName("input"); + for (var i=0;i 0) && (defAssignee != owner)) { + var divAssigned = document.getElementById("bz_assignee_edit_container"); + var divAssignedInput = document.getElementById("assigned_to"); + var divAssignedActiveCheckbox = document.getElementById("bz_assignee_edit_action"); + newButt = originalButton.cloneNode(true); + newButt.setAttribute("id","setdefaultassigneebutton"); + newButt.setAttribute("value","Def. Assignee"); + newButt.addEventListener('click',function (evt) { + if (defAssignee.length > 0) { + clickMouse(divAssignedActiveCheckbox); + divAssignedInput.value = defAssignee; + } + },true); + newButt.setAttribute("type","button"); + divAssigned.appendChild(newButt); + newButt.parentNode.insertBefore(document.createTextNode("\u00A0"),newButt); + } + var curComponentElement = document.getElementById("component"); + curComponentElement.addEventListener('change', + function(event) { + //FIXME We screw up default assignee value for unknown components + var assignee = getDefaultAssignee(); + if (assignee.length > 0) { + clickMouse(document.getElementById("bz_assignee_edit_action")); + document.getElementById("assigned_to").value = assignee; + document.getElementById("set_default_assignee").checked = false; + } + },false); +} + +// ****************** STATIC DATA ************************* + +var XMLRPCurl = "https://bugzilla.redhat.com/xmlrpc.cgi"; +// CONFIGURE: The easiest method how to set up the configuration +// value is to uncomment the following line with proper URL as +// the second parameter. Then reload the bug page and comment out +// again. +//GM_setValue("JSONURL","URL-somewhere-with-your-JSON"); +var jsonDataURL = GM_getValue("JSONURL","http://mcepl.fedorapeople.org/scripts/BugZappers_data.json"); +var debug = GM_getValue("debug",false); +var reqCounter = 0; +var msgStrs = {}; + +var RHColor = "#9E292B"; +var FedoraColor = "#002867"; +var RawhideColor = "#007700"; // or "green" +var RHITColor = "#660066"; +var SalmonPink = "#FFE0B0"; + +// Initialize data from remote URL +var XMLHTTPRequestDone = false; +var hashBugzillaName = Array(); +var hashBugzillaWholeURL = Array(); +var defAssigneeList = Array(); +var signatureFedoraString = ""; +var queryButtonAvailable = false; +var AddrArray = Array(); +GM_xmlhttpRequest({ + method: 'GET', + url: jsonDataURL, + onload: function(response) { + var data = jsonParse(response.responseText); + msgStrs = data['strings']; + signatureFedoraString = data['signature']; + hashBugzillaName = data['bugzillalabelNames']; + hashBugzillaWholeURL = data['bugzillaIDURLs']; + // [{'regexp to match component':'email address of an universal maintainer'}, ...] + AddrArray = data['CCmaintainer'], + defAssigneeList = data['defaultAssignee'], + queryButtonAvailable = data['queryButton']; + buildButtons(data['topRow'],data['bottomRow']); + if (signatureFedoraString.length > 0) { + GM_log("yes, add signature listener"); + // (or a form named "changeform") + document.forms[1].addEventListener("submit",addSignature,true); + } + + + } +}); +// ******************** MAIN ********************* + +// FOR DEBUGGING ONLY!!! +if (debug) { + GM_log("signatureFedoraString = " + signatureFedoraString); + var urlWarning = document.createElement("span"); + urlWarning.appendChild(document.createTextNode(jsonDataURL)); + urlWarning.style.fontSize = "x-small"; + var urlWarningParent = document.getElementById("bz_field_status"); + urlWarningParent.appendChild(urlWarning); +} + +// *** collect information about the bug +var bugNo = getBugNo(); +var reporter = getReporter(); +var owner = getAssignedTo(); +var CCList = getCCList(); +var product = getProduct(); +var version = getVersion(); +var issueTracker = getIssueTracker(); +var maintCCAddr = getCCMaintainer(); +var component = getComponent(); + +checkPrivateValues(); + +var login = getLogin(); +var password = GM_getValue("BZpassword"); + +//*** set the main environment +setBranding(product,version,issueTracker); + +// fix process.cgi HREFs so that to avoid confusion on IRC +if (document.location.href.search(/process.cgi/) != -1) { + fixAllHrefs(bugNo); +} + +// ---------------------------------------------- +// fix attachments +var aTable = getAttTable(); +var badAttachments = getAttachments(aTable).filter(isOctetStream); + +if (badAttachments.length>0) { + var titleElement = document.getElementsByClassName("bz_alias_short_desc_container")[0]; + titleElement.style.backgroundColor = "olive"; + titleElement.appendChild(createFixAllButton(badAttachments)); + for(var i=0;i