From f6473374cf5984ebdb3e96edc1e176ae65bc2eac Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Sun, 15 Nov 2009 23:38:56 +0100 Subject: We want to follow jetpack directory. Filtering out will be done before merge to master. --- bugzillaBugTriage.js | 1315 +++++++++++++++++++++++++++++++ install-skip-bugzilla.html | 27 + install-skip-bugzilla_soubory/style.css | 24 + install.html | 10 + pagemod.js | 26 + skip-process-bug.js | 16 + 6 files changed, 1418 insertions(+) create mode 100644 bugzillaBugTriage.js create mode 100644 install-skip-bugzilla.html create mode 100644 install-skip-bugzilla_soubory/style.css create mode 100644 install.html create mode 100644 pagemod.js create mode 100644 skip-process-bug.js diff --git a/bugzillaBugTriage.js b/bugzillaBugTriage.js new file mode 100644 index 0000000..0d323e6 --- /dev/null +++ b/bugzillaBugTriage.js @@ -0,0 +1,1315 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php + +// https://bugzilla.redhat.com/show_bug.cgi?id=451951 +// + +// EXAMPLE OF THE WORKING JETPACK FUNCTION!!! +//jetpack.future.import("pageMods"); + +//var callback = function(document) { +// jetpack.statusBar.append({ +// html: "BOOM!", +// width: 45, +// onReady: function(widget) { +// console.log("Boom!"); +// }, +// }); +//}; +//var options = {}; +//options.matches = [ +// "https://bugzilla.redhat.com/show_bug.cgi*", +// "https://bugzilla.redhat.com/process_bug.cgi"]; +//jetpack.pageMods.add(callback, options); + +// Interesting JEPs +// https://wiki.mozilla.org/Labs/Jetpack/JEP/10 -- clipboard access +// https://wiki.mozilla.org/Labs/Jetpack/JEP/17 -- page mods + +// ************* 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) { + console.logs("yes, add signature listener"); + // (or a form named "changeform") + document.forms[1].addEventListener("submit",addSignature,true); + } + + + } +}); +// ******************** MAIN ********************* + +function main(document) { + // FOR DEBUGGING ONLY!!! + if (debug) { + console.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 = $("bz_alias_short_desc_container"); + titleElement.style.backgroundColor = "olive"; + titleElement.appendChild(createFixAllButton(badAttachments)); + for(var i=0;i$.getScript('http://mcepl.fedorapeople.org/scripts/jquery.rpc.js');",function() { +console.log("jquery.rpc.js loaded"); +}); + +var options = {}; +options.matches = [ + "https://bugzilla.redhat.com/show_bug.cgi*", + "https://bugzilla.redhat.com/process_bug.cgi"]; +jetpack.pageMods.add(main, options); +jetpack.tabs.focused. +$('#header').css('backgroundColor','red') diff --git a/install-skip-bugzilla.html b/install-skip-bugzilla.html new file mode 100644 index 0000000..bf4fe87 --- /dev/null +++ b/install-skip-bugzilla.html @@ -0,0 +1,27 @@ + + + + + + Skip Bugzilla's process_bug.cgi + + + +
+

Skip Bugzilla's process_bug.cgi

+

+ When you update anything on Bugzilla, you're left on process_bug.cgi, a + POSTed page. This sucks. POST is for data, + GET is for web pages. +

+

+ When process_bug.cgi is detected, document.location is changed to the + bug's real location and any email notifications are shown with + jetpack.notifications. +

+

+ This jetpack uses some terrible screen scraping that's likely to break, + but I'll probably fix it quickly since I'm on bugzilla every day. +

+
+ diff --git a/install-skip-bugzilla_soubory/style.css b/install-skip-bugzilla_soubory/style.css new file mode 100644 index 0000000..d6c4961 --- /dev/null +++ b/install-skip-bugzilla_soubory/style.css @@ -0,0 +1,24 @@ +body { + font-size: 1.3em; + font-family: serif; +} +h1 { + font-size: 2em; + font-family: Helvetica, Arial, sans-serif; +} +p { + width: 35em; + line-height: 1.2em; +} +aside { + font-size: 0.5em; +} +footer { + font-size: 0.8em; +} +ul { + list-style-type: none; +} +li { + margin: 0.3em 0; +} diff --git a/install.html b/install.html new file mode 100644 index 0000000..d6f3a4d --- /dev/null +++ b/install.html @@ -0,0 +1,10 @@ + + + Install Jetpack + + + + Installing Bugzilla Triaging Jetpack. + + diff --git a/pagemod.js b/pagemod.js new file mode 100644 index 0000000..02d4c16 --- /dev/null +++ b/pagemod.js @@ -0,0 +1,26 @@ +jetpack.future.import("pageMods"); +var callback = function(document){ +// check the current time if it is between 9 and 5 +// 'blacklist' the sites in options.matches +var currentTime; +var currentHour; +currentTime = new Date(); +currentHour = currentTime.getHours(); +if (currentHour> 8 && currentHour <17){ + document.title = "This site is blacklisted. Get some work done!"; + $(document).find("body").css({border:"3px solid #000000"}); + $(document).find("body").children().hide(); + $(document).find("body").prepend($('

Sorry this site is blacklisted until 17:00. sadface.')); + } +}; +var options = {}; + +options.matches = ["http://*.reddit.com/*", +"http://*.cnn.com/*", +"http://*.bbc.co.uk/*", +"http://*.dpreview.com/*", +"http://dpreview.com/*", +"http://*.bloglines.com/*", +"http://bloglines.com/*"]; + +jetpack.pageMods.add(callback, options); diff --git a/skip-process-bug.js b/skip-process-bug.js new file mode 100644 index 0000000..3972893 --- /dev/null +++ b/skip-process-bug.js @@ -0,0 +1,16 @@ +jetpack.tabs.onReady(function(doc){ + var root = 'https://bugzilla.mozilla.org/', + pages = ['attachment', 'post_bug', 'process_bug'], + paths = pages.map(function(p) root + p + '.cgi'), + collision = 'Mid-air collision!'; + if (paths.some(function(p) doc.location == p) && doc.title != collision) { + var $doc = $(doc), + mail = $doc.find('#bugzilla-body > dl').text(), + bug = $($doc.find('.bz_alias_short_desc_container > a')); + /* Bail if we sense a disturbance. */ + if (bug.size() != 0) { + jetpack.notifications.show({title: 'Mail sent for ' + bug.text(), body: mail}); + doc.location = root + bug.attr('href'); + } + } +}); -- cgit