diff options
Diffstat (limited to 'bugzillaBugTriage.user.js')
-rw-r--r-- | bugzillaBugTriage.user.js | 1305 |
1 files changed, 0 insertions, 1305 deletions
diff --git a/bugzillaBugTriage.user.js b/bugzillaBugTriage.user.js deleted file mode 100644 index 1a798a4..0000000 --- a/bugzillaBugTriage.user.js +++ /dev/null @@ -1,1305 +0,0 @@ -// 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 -// @require http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js -// @require http://mcepl.fedorapeople.org/scripts/jquery.rpc.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 <stevenlevithan.com> - * 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 <tr> 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<tempT.length-1;i++) { - attList.push(parseAttachmentLine(tempT[i])); - } - } - return(attList); -} - -/* - * old - * long_desc=Xpress%20200&bug_status=NEW&bug_status=ASSIGNED - * new - * long_desc_type=substring&long_desc=Xpress%20200&bug_status=NEW&bug_status=ASSIGNED - */ - -/** - * Opens a new tab with a query for the given text in the selected component - * @param text to be searched for - * @param component string with the component name (maybe latter regexp?) - * @param product (optional) string with the product name - * @return None - */ -function queryInNewTab(text,component,product) { - // Optional parameter - if (product == null) { - product = "Fedora"; - } - var url = "https://bugzilla.redhat.com/buglist.cgi?query_format=advanced"; - if (product) { - url += "&product="+product; - } - if (component) { - url += "&component="+component; - } - if (text) { - url += "&long_desc_type=substring&long_desc="+ text.replace(" ","%20"); - } - GM_log("queryInNewTab: url = " + url); - window.open(url); -} - -function queryForSelection() { - var text = window.getSelection().toString(); - if (text.length < 1) { - text = getClipboardText(); - }; - if (text.length > 0) { - queryInNewTab(text, component); - } -} - -/** - * Sends XMLRPC request - * - * @param url string with URL of the XML-RPC interface - * @param data string with XML of the data to be sent - * @param method string -- either 'post' or 'get' - * @param callback function catching callback - */ -function sendRequest(url,data,method,callback) { - //$.rpc(url, dataType, onLoadCallback, version); - GM_xmlhttpRequest({ - method: method, - url: url, - headers: { - 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey fixAttType XMLRPC', - 'Accept': 'application/atom+xml,application/xml,text/xml', - 'Content-type': 'text/xml' - }, - data: data, - onload: callback - }); -} - -/** - * Callback function for the XMLRPC request - * - * @param ret object with xmlhttprequest response - * with attributes: - * + status -- int return code - * + statusText - * + responseHeaders - * + responseText - */ -function callBack(ret) { - if (ret.status != 200) { - alert([ret.status,ret.statusText,ret.responseHeaders, - ret.responseText]); - } - if (--reqCounter <= 0) { - setTimeout("document.location.reload()",1000); - } -} - -/** - * The worker function -- call XMLRPC to fix MIME type of the - * particular attachment - * - * @param id integer with the attachment id to be fixed - * @param type string with the new MIME type, e.g. "text/plain" - * - */ -function fixAttachById(id,type) { - var msg = new XMLRPCMessage("bugzilla.updateAttachMimeType"); - msg.addParameter({'attach_id':id, 'mime_type':type}); - msg.addParameter(login); - msg.addParameter(password); - try { - var ret = sendRequest(XMLRPCurl, - msg.xml(),'post',callBack); - } - catch (e) { - alert([e,ret]); - } - reqCounter++; -} - -function fixAllAttachments(list) { - var tmpElem = {}; - - for(var i=0;i<list.length;i++) { - tmpElem = list[i]; - fixAttachById(tmpElem[1],"text/plain"); - } -} - -function createFixAllButton(list) { - var aElem = document.createElement("a"); - aElem.setAttribute("href",""); - aElem.addEventListener('click', - function(event) {fixAllAttachments(list);}, - true); - fixElement(aElem,"","F","ix all"); - return aElem; -} - -function getTextAllLink(table,list) { - var AList = table.getElementsByTagName("a"); - var tElem = {}; - var t2Elem = {}; - var aElem = {}; - var hStr = ""; - var vAllElem = {}; - - for(var i=0;i<AList.length;i++) { - tElem = AList[i]; - if (tElem.hasAttribute("href")) { - hStr = tElem.getAttribute("href"); - } else { - hStr = ""; - } - if(hStr.indexOf("action=enter") != -1) { - vAllElem = tElem; - } - } -// tdElement.parentNode.insertBefore(tElem,tdElement.nextSibling); -// tdElement.parentNode.insertBefore(document.createElement("td"), -// tdElement.nextSibling); -} - -function addTextLink(row) { - var aList = row[row.length-1].getElementsByTagName("a"); - var curElem = aList[aList.length-1]; - var tElem = {}; - var t2Elem = {}; - - curElem.parentNode.appendChild(document.createTextNode(" ")); - t2Elem = document.createTextNode("Text"); - tElem = document.createElement("a"); - tElem.setAttribute("href",""); - tElem.addEventListener('click', - function(event) { - fixAttachById(row[1],"text/plain"); - }, - true); - tElem.appendChild(t2Elem); - curElem.parentNode.appendChild(document.createElement("br")); - curElem.parentNode.appendChild(tElem); -} - -function isOctetStream(element, index, array) { - var inArray = ["application/octet-stream","text/x-log"]; - return(inArray.indexOf(element[2]) != -1); -} - -//=========================== - - -/** - * Find the next (or previous) sibling element of given tagName - * starting from given element. - * - * @param startElement element from which to start searching - * @param tagName string tagName of the searched for element (case insensitive) - * @param forward boolean optional should we search forward or backward? - * @return element of the given tagName or null - */ -function findNextSiblingByTagName(startElement,tagName,forward) { - if (forward === null) { // missing optional argument - forward = true; - } - var tempElement = startElement; - tagName = tagName.toUpperCase(); - while (tempElement && tempElement.tagName != tagName) { - if (forward) { - tempElement = tempElement.nextSibling; - } else { - tempElement = tempElement.previousSibling; - } - } - return tempElement; -} - -/** - * Select option with given label on the <SELECT> 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 + "<b><u>" + accKey + "</u></b>" + 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<AList.length;i++) { - curA = AList[i]; - if (curA.hasAttribute("href")) { - hrefStr = curA.getAttribute("href"); - if (reProcess.test(hrefStr)) { - hrefStr = "show_bug.cgi?id="+bugNo.toString()+hrefStr; - curA.setAttribute("href",hrefStr); - } - } - } -} - -/** Insert row of buttons before the marked element - * @param anchor element before which the row of buttons will be inserted - * @param array array of data for buttons to be generated - */ -function generateToolBar(anchor,array) { - for (var i=0; i<array.length; i++) { - var butt = array[i]; - addNewButton(anchor, butt['idx'], - butt['msg'], butt['string'], butt['state'], butt['parameter'], butt['submit']); - } -} - -/** - * make sure that prefs.js contain password for bugzilla - * @return None - */ -function checkPrivateValues() { - var password = GM_getValue("BZpassword",""); - if (password == "") { - password = prompt("Enter your Bugzilla password",""); - GM_setValue("BZpassword",password); - } -} - -/** - * There is a login printed on each page, go get it. - * @return string with the login - */ - function getLogin() { - var tmpElement = {}; - var tmpText = ""; - var divHeaderElement = document.getElementById("header"); - - var headerLiElements = divHeaderElement.getElementsByTagName("ul")[0].getElementsByTagName("li"); - var loginLIElement = headerLiElements[headerLiElements.length-1]; - var loginText = strip(loginLIElement.lastChild.textContent); - return loginText; -} - -/** - * Main executable functioning actually building all buttons on the page -- separated into function, so that - * it could be called from onload method of the GM_XMLHTTPRequest. - * @param jsonList Array created from JSON - * @return none - */ -function buildButtons(above,below) { - // TODO: I don't need this now and it isn't compatible with new style - // generalPurposeCureForAllDisease driving addNewButton. - //// Just for fixing wrong CC list - //if (isInList(login,CCList) && !isInList(maintCCAddr,CCList)) { - // addNewButton(IBList[1],"swapXGLMainToCCList","Swap -maint to CC", - // swapXGLMainToCCListHandler); - //} - - //---------------------------------------------- - //Generate a list of <input> elements in the page - var IBList = []; - var IBRawList = document.getElementsByTagName("input"); - for (var i=0;i<IBRawList.length;i++) { - if ((IBRawList[i].hasAttribute("type")) && - (IBRawList[i].getAttribute("type")=="submit")) { - IBList = IBList.concat(IBRawList[i]); - } - } - - // BUTTONS ON THE BOTTOM OF THE FORM - // Create a new SUBMIT button adding current owner of the bug to - // the CC list - var IBLast = IBList[IBList.length-4]; - addNewButton(IBLast,"changeOwnerbtn","reASSIGN", - "","ASSIGNED","NODEFAULTASSIGNEE"); - - // BUTTONS ABOVE THE COMMENT BOX - var textCommentElement = document.getElementById("comment"); - var brElement = document.createElement("br"); - textCommentElement.parentNode.insertBefore(brElement,textCommentElement); - //var brElement = findNextSiblingByTagName(textCommentElement,"BR",false); - var insertAfterElement = brElement; - generateToolBar(insertAfterElement,above); - - // BUTTONS BELOW THE COMMENT BOX - generateToolBar(originalButton,below); - - // FIXME put this somehow into addNewButton and generalPurposeCureForAllDisease - // framework - if (queryButtonAvailable){ - // Add query search button - var privateCheckbox = document.getElementById("newcommentprivacy"); - var newPosition = privateCheckbox.nextSibling.nextSibling.nextSibling; - var newButt = originalButton.cloneNode(true); - newButt.setAttribute("id","newqueryintab"); - newButt.setAttribute("value","Query for string"); - newButt.addEventListener('click',function (evt) { - queryForSelection(); - },true); - newButt.setAttribute("type","button"); - newPosition.parentNode.insertBefore(newButt,newPosition); - newPosition.parentNode.insertBefore(document.createTextNode("\u00A0"),newButt); - } - // Add setting default assignee - var defAssignee = getDefaultAssignee(); - if ((defAssignee.length > 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<badAttachments.length;i++) { - addTextLink(badAttachments[i]); - } -} - -var originalButton = document.getElementById("commit"); // source button to be copied from -originalButton.setAttribute("accesskey",'s'); -originalButton.setAttribute("value","Submit"); |