// Released under the MIT/X11 license // http://www.opensource.org/licenses/mit-license.php "use strict"; var bugURL = "https://bugzilla.redhat.com/show_bug.cgi?id="; var BTSPrefNS = "bugzilla-triage.setting."; // Shared contstants var NumberOfFrames = 7; // constants var SalmonPink = new Color(255, 224, 176); // RGB 255, 224, 176; HSL 36, 2, // 85 var ReporterColor = new Color(255, 255, 166); // RGB 255, 255, 166; HSL 60, 2, // 83 // global variables var config = {}; var constantData = {}; // This should be probably eliminated ASAP or // or done by other means. TODO var equivalentComponents = null; /** * central handler processing messages from the main script. */ self.on('message', function onMessage(msg) { myDebug("onMessage - incoming : msg.cmd = " + msg.cmd); switch (msg.cmd) { case "ReloadThePage": document.location.reload(true); break; case "queryLocal": queryInNewTab(msg.data, getComponent(), getProduct(), equivalentComponents); break; case "ReturningLogData": timeSheetRecordsPrinter(msg.data, new Date()); break; case "CreateButtons": constantData = msg.data.constData; config = msg.data.config; equivalentComponents = ("equivalentComponents" in constantData) ? constantData.equivalentComponents : null; generateButtons(msg.data.instPkgs, msg.data.kNodes); completeInit(); break; case "Error": alert("Error " + msg.data); break; case "Unhandled": break; default: if (RHOnMessageHandler) { RHOnMessageHandler(msg, [MozOnMessageHandler]); } else { console.error("Error: unknown RPC call " + msg.toSource()); } } }); /** * @param cmd * Object with all commands to be executed * * PROBLEM: according to * https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference\ * /Statements/for...in there is no guaranteed order of execution of commands * (i.e., key, commentObj[key] pairs) in for..in cycle. According to * https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference\ * /Operators/Special_Operators/delete_Operator#Cross-browser_issues it seems * that everywhere except of Internet Explorer this should work well, but * waiting impatiently when this bite us. */ function executeCommand(cmdObj) { for (var key in cmdObj) { centralCommandDispatch(key, cmdObj[key]); } } /** * Actual execution function * * @param cmdLabel * String with the name of the command to be executed * @param cmdParams * Object with the appropriate parameters for the command */ function centralCommandDispatch (cmdLabel, cmdParams) { myDebug("centralCommandDispatch : cmdLabel = " + cmdLabel); switch (cmdLabel) { case "name": case "position": break; case "resolution": case "product": case "component": case "version": case "priority": selectOption(cmdLabel, cmdParams); break; case "status": selectOption("bug_status", cmdParams); break; case "platform": selectOption("rep_platform", cmdParams); break; case "os": selectOption("op_sys", cmdParams); break; case "severity": selectOption("bug_severity", cmdParams); break; case "target": selectOption("target_milestone", cmdParams); break; case "addKeyword": addStuffToTextBox("keywords",cmdParams); break; case "removeKeyword": removeStuffFromTextBox("keywords", cmdParams); break; case "addWhiteboard": addStuffToTextBox("status_whiteboard",cmdParams); break; case "removeWhiteboard": removeStuffFromTextBox("status_whiteboard",cmdParams); break; case "assignee": changeAssignee(cmdParams); break; case "qacontact": clickMouse("bz_qa_contact_edit_action"); document.getElementById("qa_contact").value = cmdParams; break; case "url": clickMouse("bz_url_edit_action"); document.getElementById("bug_file_loc").value = cmdParams; break; // TODO dependson/blocked doesn't work. Find out why. case "addDependsOn": clickMouse("dependson_edit_action"); addStuffToTextBox("dependson", cmdParams); break; case "removeDependsOn": clickMouse("dependson_edit_action"); removeStuffFromTextBox("dependson", cmdParams); break; case "addBlocks": clickMouse("blocked_edit_action"); addStuffToTextBox("blocked", cmdParams); break; case "removeBlocks": clickMouse("blocked_edit_action"); removeStuffFromTextBox("blocked", cmdParams); break; case "comment": addStuffToTextBox("comment", cmdParams); break; case "commentIdx": throw "There should be no commentIdx here at all."; break; case "setNeedinfo": // cmdParams are actually ignored for now; we may in future // distinguish different actors to be target of needinfo setNeedinfoReporter(); break; case "addCC": addToCCList(cmdParams); break; case "queryStringOurBugzilla": queryForSelection(); break; // TODO flags, see also case "commit": if (cmdParams) { // Directly commit the form document.forms.namedItem("changeform").submit(); } break; default: if (RHcentralCommandDispatch) { RHcentralCommandDispatch(cmdLabel, cmdParams); } else { console.error("Unknown command:\n" + cmdLabel + "\nparameters:\n" + cmdParams); } break; } } /** * Change assignee of the bug * * @param newAssignee * String with the email address of new assigneeAElement or 'default' * if the component's default assignee should be used. Value null * clears "Reset Assignee to default for component" checkbox * @return none */ function changeAssignee (newAssignee) { var defAssigneeButton = null; // Previous assignee should know what's going on in his bug addToCCList(getOwner()); // Optional value null if (newAssignee === null) { document.getElementById("set_default_assignee").removeAttribute( "checked"); return ; } if (getDefaultAssignee) { if (newAssignee === "default") { var defAss = getDefaultAssignee(); if (defAss) { newAssignee = defAss; } else { return ; } } } var saveFocus = document.activeElement; if (newAssignee) { clickMouse("bz_assignee_edit_action"); document.getElementById("assigned_to").value = newAssignee; document.getElementById("set_default_assignee").checked = false; defAssigneeButton = document.getElementById("defassignee_btn"); if (defAssigneeButton) { defAssigneeButton.style.display = "none"; } } saveFocus.focus(); } /** * Adds new option to the 'comment_action' scroll down box * * @param pkg * String package name * @param cmd * String with the name of the command If the 'comment_action' scroll * down box doesn't exist, this function will set up new one. */ function addToCommentsDropdown (cmdObj) { var select = document.getElementById("comment_action"); if (!select) { config.commandsList = []; document.getElementById("comments").innerHTML += "
" + " " + " " + "
"; select = document.getElementById("comment_action"); select.addEventListener("change", function (evt) { var value = select.options[select.selectedIndex].value; executeCommand(config.commandsList[value]); }, false); } var opt = document.createElement("option"); var objIdx = config.commandsList.length + 1; opt.value = objIdx; config.commandsList[objIdx] = cmdObj; opt.textContent = cmdObj.name; select.appendChild(opt); } /** * Generate button based on */ function generateButtons (pkgs, kNodes) { var topRowPosition = "topRowPositionID"; var bottomRowPosition = "commit"; // ========================================================= if (kNodes && window.location.hostname in kNodes) { var killConf = kNodes[window.location.hostname]; killNodes(document, killConf[0], killConf[1]); } // create anchor for the top toolbar var commentBox = document.getElementById("comment"); var brElement = document.createElement("br"); brElement.setAttribute("id",topRowPosition); commentBox.parentNode.normalize(); commentBox.parentNode.insertBefore(brElement, commentBox); for (var pkg in pkgs) { for (var cmdIdx in pkgs[pkg]) { var cmdObj = pkgs[pkg][cmdIdx]; if (cmdObj.position !== undefined) { switch (cmdObj.position) { case "topRow": createNewButton(topRowPosition, false, cmdObj); break; case "bottomRow": createNewButton(bottomRowPosition, false, cmdObj); break; case "dropDown": addToCommentsDropdown(cmdObj); break; default: // [+-]ID var firstChr = cmdObj.position.charAt(0); var newId = cmdObj.position.substr(1); createNewButton(newId, firstChr === "+", cmdObj); break; } } else { console.error("generateButtons : rejected cmdObj = " + cmdObj.toSource()); } } } } function setConfigurationButton () { var additionalButtons = document.querySelector("#bugzilla-body *.related_actions"); var configurationButtonUI = document.createElement("li"); configurationButtonUI.innerHTML = "\u00A0-\u00A0" + "Triage configuration"; additionalButtons.appendChild(configurationButtonUI); document.getElementById("configurationButton").addEventListener( "click", function(evt) { self.postMessage(new Message("ChangeJSONURL", null)); evt.stopPropagation(); evt.preventDefault(); }, false); } /** * Complete startup, mainly run alternate inits for non-standard BZ with proper * arguments * */ function completeInit() { // TODO: add flags, and priority or others bits. var things = { attachments: new AttachList(document), comments: new CommentList(document) }; if (RHBZinit) { RHBZinit(things); } things.comments.colorComments(); if (tweakBugzilla && config.verboseInlineHistory) { tweakBugzilla(things, constantData); } } function startup() { // First, preflight check ... if we are not logged in, there // is nothing we can do. myDebug("startup: Starting!"); var logoutLink = Array.some(document.links, function (x) { return x.search === "?logout=1" ; }); if (logoutLink) { if (document.getElementById("brElementPlace_location")) { console.error("Hit multiple firing protection!"); return null; // This should just finish whole content script without // doing any harm to anybody. } else { myDebug("Didn't hit multiple firing protection!"); } // Prepare for query buttons // element ID brElementPlace_location is later used in JSON files // Stay with this add_comment element even if RH BZ upgrades, this seems // to be generally much more stable (even with other bugzillas, e.g. // b.gnome.org) // then some getElementById. var commentArea = document.getElementsByClassName("bz_section_additional_comments")[0]; if (commentArea) { var brElementPlacer = commentArea.getElementsByTagName("br"); brElementPlacer = brElementPlacer[0]; if (brElementPlacer) { brElementPlacer.setAttribute("id","brElementPlacer_location"); brElementPlacer.parentNode.insertBefore(document.createElement("br"), brElementPlacer); } } // Prepare for adding external bugs var a0Elements = document.getElementById("et0"); if (a0Elements) { a0Elements.setAttribute("id", "external_bugs_headline"); } // So, now we know we are logged in, so we can get to // the real work. setConfigurationButton(); submitHandlerInstalled = false; self.postMessage(new Message("GetInstalledPackages", { location: window.location.href, login: getLogin(), })); } } startup();