diff options
-rw-r--r-- | data/bzpage.js | 671 | ||||
-rw-r--r-- | data/color.js (renamed from lib/color.js) | 0 | ||||
-rw-r--r-- | data/rhbzpage.js | 26 | ||||
-rw-r--r-- | data/util.js (renamed from lib/util.js) | 0 | ||||
-rw-r--r-- | lib/libbugzilla.js | 273 | ||||
-rw-r--r-- | lib/main.js | 104 |
6 files changed, 571 insertions, 503 deletions
diff --git a/data/bzpage.js b/data/bzpage.js index def12a7..086fe44 100644 --- a/data/bzpage.js +++ b/data/bzpage.js @@ -3,16 +3,23 @@ // 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; exports.NumberOfFrames = NumberOfFrames; -var BTSPrefNS = "bugzilla-triage.setting."; -exports.BTSPrefNS = BTSPrefNS; -var BTSPassRealm = "BTSXMLRPCPass"; -// ============================================ +// 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 constantData = {}; // This should be probably eliminated ASAP or + // or done by other means. TODO +var submitHandlerInstalled = false; // for setUpLogging +// ============================================ /** * object to pack messaging. Use as in postMessage(new Message("GetPassword", { @@ -39,64 +46,51 @@ NotLoggedinException.prototype.toString = function () { }; exports.NotLoggedinException = NotLoggedinException; -// ==================================================================================== /** - * In case URL contains alias, not the real bug number, get the real bug no - * from the XML representation. Sets correct value to this.bugNo. - */ -nonTestedFunction getRealBugNo() { - console.log("We have to deal with bug aliased as " + this.bugNo); - var that = this; - // https://bugzilla.redhat.com/show_bug.cgi?ctype=xml&id=serialWacom - Request({ - url: this.win.location.href+"&ctype=xml", - onComplete: function(response) { - if (response.status === 200) { - var xmlRepr = response.xml; - var bugID = parseInt(xmlRepr.getElementsByTagName("bug_id")[0].textContent, 10); - if (isNaN(bugID)) { - throw new Error("Cannot get bug no. even from XML representation!"); - } - that.bugNo = bugID; - console.log("The real bug no. is " + bugID); +* central handler processing messages from the main script. +*/ +onMessage = function onMessage(msg) { + console.log("onMessage: msg = " + msg.toSource()); + switch (msg.cmd) { + case "ReloadThePage": + document.location.reload(true); + break; + case "RetClipboard": + if (msg.data.cmd == "queryLocal") { + queryInNewTab(msg.data.data, getComponent(), getProduct()); + } else if (msg.data.cmd == "queryUpstream") { + // } - } - }).get(); -} + break; + case "CreateButtons": + constantData = msg.data.constData; + generateButtons(msg.data.instPkgs); + break; + case "Error": + alert("Error " + msg.data); + break; + case "Unhandled": + break; + default: + 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. */ -nonTestedFunction getInstalledPackages(cfg) { - var installedPackages = {}; - var enabledPackages = []; - - // Collect enabled packages per hostname (plus default ones) - if (cfg.gJSONData && ("commentPackages" in cfg.gJSONData)) { - if ("enabledPackages" in cfg.gJSONData.configData) { - var epObject = cfg.gJSONData.configData.enabledPackages; - if (this.hostname in epObject) { - enabledPackages = enabledPackages.concat(epObject[this.hostname].split(/[,\s]+/)); - } - if ("any" in epObject) { - enabledPackages = enabledPackages.concat(epObject.any.split(/[,\s]+/)); - } - } - - if ((enabledPackages.length === 1) && (enabledPackages[0] === "all")) { - enabledPackages = []; - for (var key in cfg.gJSONData.commentPackages) { - enabledPackages.push(key); - } - } - - enabledPackages.forEach(function (pkg, idx, arr) { - if (pkg in cfg.gJSONData.commentPackages) { - installedPackages[pkg] = cfg.gJSONData.commentPackages[pkg]; - } - }); +function executeCommand(cmdObj) { + for (var key in cmdObj) { + centralCommandDispatch(key, cmdObj[key]); } - return installedPackages; } /** @@ -105,125 +99,98 @@ nonTestedFunction getInstalledPackages(cfg) { * @param cmdLabel String with the name of the command to be executed * @param cmdParams Object with the appropriate parameters for the command */ -nonTestedFunction centralCommandDispatch (cmdLabel, cmdParams) { +function centralCommandDispatch (cmdLabel, cmdParams) { switch (cmdLabel) { case "resolution": case "product": case "component": case "version": case "priority": - this.selectOption(cmdLabel, cmdParams); + selectOption(cmdLabel, cmdParams); break; case "status": - this.selectOption("bug_status", cmdParams); + selectOption("bug_status", cmdParams); break; case "platform": - this.selectOption("rep_platform", cmdParams); + selectOption("rep_platform", cmdParams); break; case "os": - this.selectOption("op_sys", cmdParams); + selectOption("op_sys", cmdParams); break; case "severity": - this.selectOption("bug_severity", cmdParams); + selectOption("bug_severity", cmdParams); break; case "target": - this.selectOption("target_milestone", cmdParams); + selectOption("target_milestone", cmdParams); break; case "addKeyword": - this.addStuffToTextBox("keywords",cmdParams); + addStuffToTextBox("keywords",cmdParams); break; case "removeKeyword": - this.removeStuffFromTextBox("keywords", cmdParams); + removeStuffFromTextBox("keywords", cmdParams); break; case "addWhiteboard": - this.addStuffToTextBox("status_whiteboard",cmdParams); + addStuffToTextBox("status_whiteboard",cmdParams); break; case "removeWhiteboard": - this.removeStuffFromTextBox("status_whiteboard",cmdParams); + removeStuffFromTextBox("status_whiteboard",cmdParams); break; case "assignee": - this.changeAssignee(cmdParams); + changeAssignee(cmdParams); break; case "qacontact": - this.clickMouse("bz_qa_contact_edit_action"); - this.doc.getElementById("qa_contact").value = cmdParams; + clickMouse("bz_qa_contact_edit_action"); + document.getElementById("qa_contact").value = cmdParams; break; case "url": - this.clickMouse("bz_url_edit_action"); - this.doc.getElementById("bug_file_loc").value = cmdParams; + clickMouse("bz_url_edit_action"); + document.getElementById("bug_file_loc").value = cmdParams; break; // TODO dependson/blocked doesn't work. Find out why. case "addDependsOn": - this.clickMouse("dependson_edit_action"); - this.addStuffToTextBox("dependson", cmdParams); + clickMouse("dependson_edit_action"); + addStuffToTextBox("dependson", cmdParams); break; case "removeDependsOn": - this.clickMouse("dependson_edit_action"); - this.removeStuffFromTextBox("dependson", cmdParams); + clickMouse("dependson_edit_action"); + removeStuffFromTextBox("dependson", cmdParams); break; case "addBlocks": - this.clickMouse("blocked_edit_action"); - this.addStuffToTextBox("blocked", cmdParams); + clickMouse("blocked_edit_action"); + addStuffToTextBox("blocked", cmdParams); break; case "removeBlocks": - this.clickMouse("blocked_edit_action"); - this.removeStuffFromTextBox("blocked", cmdParams); + clickMouse("blocked_edit_action"); + removeStuffFromTextBox("blocked", cmdParams); break; case "comment": - this.addStuffToTextBox("comment", cmdParams); + addStuffToTextBox("comment", cmdParams); break; case "commentIdx": - var commentText = this.commentStrings[cmdParams]; - this.addStuffToTextBox("comment", commentText); + 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 - this.setNeedinfoReporter(); + setNeedinfoReporter(); break; case "addCC": - this.addToCCList(cmdParams); + addToCCList(cmdParams); break; case "queryStringOurBugzilla": - this.queryForSelection(); + queryForSelection(); break; // TODO flags, see also - case "commit": if (cmdParams) { - // Directly commit the form - this.doc.forms.namedItem("changeform").submit(); + // Directly commit the form + document.forms.namedItem("changeform").submit(); } break; } } /** - * Take the ID of the package/id combination, and execute it - * - * @param String combined package + "//" + id combination - * Fetches the command object from this.installedPackages and then - * goes through all commands contained in it, and calls - * this.centralCommandDispatch to execute them. - * - * 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. - */ -nonTestedFunction executeCommand (cmd) { - var cmdArr = cmd.split("//"); - var commentObj = this.packages[cmdArr[0]][cmdArr[1]]; - - for (var key in commentObj) { - this.centralCommandDispatch(key,commentObj[key]); - } -} - -/** * Change assignee of the bug * * @param newAssignee String with the email address of new assigneeAElement @@ -231,21 +198,21 @@ nonTestedFunction executeCommand (cmd) { * Value null clears "Reset Assignee to default for component" checkbox * @return none */ -nonTestedFunction changeAssignee (newAssignee) { +function changeAssignee (newAssignee) { var defAssigneeButton = null; // Previous assignee should know what's going on in his bug - this.addToCCList(this.owner); + addToCCList(getOwner()); // Optional value null if (newAssignee === null) { - this.doc.getElementById("set_default_assignee").removeAttribute( + document.getElementById("set_default_assignee").removeAttribute( "checked"); return ; } - if (this.getDefaultAssignee) { + if (getDefaultAssignee) { if (newAssignee === "default") { - var defAss = this.getDefaultAssignee(); + var defAss = getDefaultAssignee(); if (defAss) { newAssignee = defAss; } else { @@ -255,10 +222,10 @@ nonTestedFunction changeAssignee (newAssignee) { } if (newAssignee) { - this.clickMouse("bz_assignee_edit_action"); - this.doc.getElementById("assigned_to").value = newAssignee; - this.doc.getElementById("set_default_assignee").checked = false; - defAssigneeButton = this.doc.getElementById("setDefaultAssignee_btn"); + clickMouse("bz_assignee_edit_action"); + document.getElementById("assigned_to").value = newAssignee; + document.getElementById("set_default_assignee").checked = false; + defAssigneeButton = document.getElementById("setDefaultAssignee_btn"); if (defAssigneeButton) { defAssigneeButton.style.display = "none"; } @@ -273,34 +240,26 @@ nonTestedFunction changeAssignee (newAssignee) { * If the 'comment_action' scroll down box doesn't exist, this * function will set up new one. */ -nonTestedFunction addToCommentsDropdown (pkg, cmd) { - var select = this.doc.getElementById("comment_action"); +function addToCommentsDropdown (cmdObj) { + var select = document.getElementById("comment_action"); if (!select) { - var that = this; - this.doc.getElementById("comments").innerHTML += + document.getElementById("comments").innerHTML += "<div id='make_bugzilla_comment_action'>" + " <label for='comment_action'>Add Comment: </label>" + " <select id='comment_action'>" + " <option value=''>-- Select Comment from List --</option>" + "</div>"; - select = this.doc.getElementById("comment_action"); + select = document.getElementById("comment_action"); select.addEventListener("change", function (evt) { - var value = ""; - var valueElement = that.doc.getElementById("comment_action"); - if (valueElement) { - var selIdx = valueElement.selectedIndex; - value = valueElement.options[selIdx].value; - console.log("value = " + value); - } else { - return; - } - that.executeCommand(value); + var value = select.options[select.selectedIndex].value; + log("value = " + value); + executeCommand(value); }, false); } - var opt = this.doc.createElement("option"); - opt.value = pkg + "//" + cmd; - opt.textContent = this.packages[pkg][cmd].name; + var opt = document.createElement("option"); + opt.value = cmdObj; + opt.textContent = cmdObj.name; select.appendChild(opt); } @@ -315,20 +274,19 @@ nonTestedFunction addToCommentsDropdown (pkg, cmd) { * @param Boolean breakBefore if there should be a <br> element before. * @return none */ -nonTestedFunction createDeadLink (id, text, parent, callback, params, before, covered, accesskey) { - var that = this; - params = util.valToArray(params); +function createDeadLink (id, text, parent, callback, params, before, covered, accesskey) { + params = valToArray(params); var locParent = {}; // Yes, I want != here, not !== if (covered != null) { - locParent = this.doc.createElement(covered); + locParent = document.createElement(covered); parent.appendChild(locParent); } else { locParent = parent; } - var newAElem = this.doc.createElement("a"); + var newAElem = document.createElement("a"); newAElem.setAttribute("id", id); if (accesskey) { newAElem.setAttribute("accesskey", accesskey); @@ -337,15 +295,15 @@ nonTestedFunction createDeadLink (id, text, parent, callback, params, before, co newAElem.textContent = text; newAElem.addEventListener("click", function(evt) { - callback.apply(that, params); + callback(params); evt.stopPropagation(); evt.preventDefault(); }, false); if ((before === "br") || (before === true)) { - locParent.appendChild(this.doc.createElement("br")); + locParent.appendChild(document.createElement("br")); } else if (before === "dash") { - locParent.appendChild(this.doc.createTextNode("\u00A0-\u00A0")); + locParent.appendChild(document.createTextNode("\u00A0-\u00A0")); } locParent.appendChild(newAElem); @@ -362,44 +320,42 @@ nonTestedFunction createDeadLink (id, text, parent, callback, params, before, co * @param id String which command to take * @return none */ -nonTestedFunction createNewButton (location, after, pkg, id) { - var that = this; - var cmdObj = this.packages[pkg][id]; - var newId = id + "_btn"; - var label = cmdObj.name; +function createNewButton (location, after, cmdObj) { + var newId = cmdObj.name.toLowerCase().replace(/[^a-z0-9]+/,"","g") + "_btn"; // protection against double-firings - if (this.doc.getElementById(newId)) { - console.log("Element with id " + newId + "already exists!"); + if (document.getElementById(newId)) { + console.log("Element with id " + newId + " already exists!"); return ; } // creation of button might be conditional on existence of data in constantData if ("ifExist" in cmdObj) { - if (!(cmdObj.ifExist in this.constantData)) { + // We do have constantData now, but we shouldn't TODO + if (!(cmdObj.ifExist in constantData)) { return ; } } - var newButton = this.doc.createElement("input"); + var newButton = document.createElement("input"); newButton.setAttribute("id", newId); newButton.setAttribute("type", "button"); - newButton.value = label; + newButton.value = cmdObj.name; newButton.addEventListener("click", function(evt) { - that.executeCommand(pkg + "//" + id); + executeCommand(cmdObj); }, false); - var originalLocation = this.doc.getElementById(location); + var originalLocation = document.getElementById(location); try { if (after) { originalLocation.parentNode.insertBefore(newButton, originalLocation.nextSibling); - originalLocation.parentNode.insertBefore(this.doc + originalLocation.parentNode.insertBefore(document .createTextNode("\u00A0"), newButton); } else { originalLocation.parentNode.insertBefore(newButton, originalLocation); - originalLocation.parentNode.insertBefore(this.doc + originalLocation.parentNode.insertBefore(document .createTextNode("\u00A0"), originalLocation); } } catch (e) { @@ -412,60 +368,52 @@ nonTestedFunction createNewButton (location, after, pkg, id) { } /** - * + * Generate button based on */ -nonTestedFunction generateButtons () { +function generateButtons (pkgs) { var topRowPosition = "topRowPositionID"; var bottomRowPosition = "commit"; // create anchor for the top toolbar - var commentBox = this.doc.getElementById("comment"); - var brElement = this.doc.createElement("br"); + 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 this.packages) { - for (var cmdIdx in this.packages[pkg]) { - var cmdObj = this.packages[pkg][cmdIdx]; + for (var pkg in pkgs) { + for (var cmdIdx in pkgs[pkg]) { + var cmdObj = pkgs[pkg][cmdIdx]; switch (cmdObj.position) { case "topRow": - this.createNewButton(topRowPosition, false, pkg, cmdIdx); + createNewButton(topRowPosition, cmdObj, false); break; case "bottomRow": - this.createNewButton(bottomRowPosition, false, pkg, cmdIdx); + createNewButton(bottomRowPosition, cmdObj, false); break; case "dropDown": - this.addToCommentsDropdown(pkg,cmdIdx); + addToCommentsDropdown(cmdObj); break; default: // [+-]ID var firstChr = cmdObj.position.charAt(0); var newId = cmdObj.position.substr(1); - this.createNewButton(newId, firstChr === "+", pkg, cmdIdx); + createNewButton(newId, firstChr === "+", cmdObj); break; } } } } -nonTestedFunction setConfigurationButton () { - var additionalButtons = this.doc.querySelector("#bugzilla-body *.related_actions"); - var configurationButtonUI = this.doc.createElement("li"); +function setConfigurationButton () { + var additionalButtons = document.querySelector("#bugzilla-body *.related_actions"); + var configurationButtonUI = document.createElement("li"); configurationButtonUI.innerHTML = "\u00A0-\u00A0<a href='' id='configurationButton'>" + "Triage configuration</a>"; additionalButtons.appendChild(configurationButtonUI); - this.doc.getElementById("configurationButton").addEventListener( + document.getElementById("configurationButton").addEventListener( "click", function(evt) { - var prfNm = BTSPrefNS+"JSONURL"; - var url = preferences.get(prfNm,""); - - var reply = prompts.prompt("New location of JSON configuration file", url); - if (reply) { - preferences.set(prfNm, reply.trim()); - prompts.alert("For now, you should really restart Firefox!"); - } - + postMessage(new Message("ChangeJSONURL", null)); evt.stopPropagation(); evt.preventDefault(); }, false); @@ -480,18 +428,18 @@ nonTestedFunction setConfigurationButton () { * @return String with the address or null * */ -nonTestedFunction parseMailto(aElement) { +function parseMailto(aElement) { var emailStr = "", hrefStr = ""; // use url utils if (aElement) { hrefStr = decodeURIComponent(aElement.getAttribute("href")); - emailStr = hrefStr.split(":")[1]; - // - if (emailStr === undefined) { - var params = util.getParamsFromURL("https://" + this.hostname + "/" + hrefStr); - emailStr = decodeURI(params.login); + emailStr = hrefStr.split(":"); + // workaround for Gnome bugzilla ... no mailto: here. + if (emailStr.length < 2) { + var params = getParamsFromURL("https://" + window.location.hostname + "/" + hrefStr); + return decodeURI(params.login); } - return emailStr; + return emailStr[1]; } return null; } @@ -501,53 +449,58 @@ nonTestedFunction parseMailto(aElement) { * * @return string */ -nonTestedFunction getReporter () { - var reporterElement = this.getOptionTableCell("bz_show_bug_column_2", "Reported"); +function getReporter () { + var reporterElement = getOptionTableCell("bz_show_bug_column_2", "Reported"); // RH Bugzilla after upgrade to 3.6.2 moved the information to other column if (!reporterElement) { - reporterElement = this.getOptionTableCell("bz_show_bug_column_1", "Reported", true); + reporterElement = getOptionTableCell("bz_show_bug_column_1", "Reported", true); } // Maemo calls the label "Reporter" and it doesn't have ids on table columns ... TODO(maemo) - - return this.parseMailto(reporterElement); + return parseMailto(reporterElement); } -nonTestedFunction getComponent() { - var elem = this.doc.getElementById("component"); +function getComponent() { + var elem = document.getElementById("component"); if (elem) { return elem.value; } return null; } +function getProduct() { + var elem = document.getElementById("product"); + if (elem) { + return elem.value; + } + return null; +} -nonTestedFunction commentsWalker (fce) { - var comments = this.doc.getElementById("comments").getElementsByClassName( - "bz_comment"); +function commentsWalker (fce) { + var comments = document.getElementById("comments"). + getElementsByClassName("bz_comment"); Array.forEach(comments, function(item) { fce(item); - }, this); + }); } /** * Set background color of all comments made by reporter in ReporterColor color * */ -nonTestedFunction checkComments () { - var that = this; - var reporterRE = new RegExp(this.getReporter()); - this.commentsWalker(function(x) { - var email = that.parseMailto(x.getElementsByClassName("vcard")[0] +function checkComments () { + var reporterRE = new RegExp(getReporter()); + commentsWalker(function(x) { + var email = parseMailto(x.getElementsByClassName("vcard")[0] .getElementsByTagName("a")[0]); if (reporterRE.test(email)) { - x.style.backgroundColor = that.ReporterColor.toString(); + x.style.backgroundColor = ReporterColor.toString(); } }); } -nonTestedFunction collectComments () { +function collectComments () { var outStr = ""; - this.commentsWalker(function(x) { + commentsWalker(function(x) { outStr += x.getElementsByTagName("pre")[0].textContent + "\n"; }); return outStr.trim(); @@ -564,35 +517,35 @@ nonTestedFunction collectComments () { * @return none * */ -nonTestedFunction selectOption (id, label, fireEvent) { +function selectOption (id, label, fireEvent) { if (!fireEvent) { fireEvent = true; } - var sel = this.doc.getElementById(id); + var sel = document.getElementById(id); sel.value = label; if (fireEvent) { - var intEvent = this.doc.createEvent("HTMLEvents"); + var intEvent = document.createEvent("HTMLEvents"); intEvent.initEvent("change", true, true); sel.dispatchEvent(intEvent); } } -nonTestedFunction selectOptionByLabel(id, label, fireEvent) { +function selectOptionByLabel(id, label, fireEvent) { if (!fireEvent) { fireEvent = true; } - var sel = this.doc.getElementById(id); + var sel = document.getElementById(id); var labelRE = new RegExp(label.trim()); var ourOption = Array.filter(sel.options, function (op) { return op.textContent.trim() === label; - }, this); + }); if (ourOption[0]) { sel.value = ourOption[0].value; } if (fireEvent) { - var intEvent = this.doc.createEvent("HTMLEvents"); + var intEvent = document.createEvent("HTMLEvents"); intEvent.initEvent("change", true, true); sel.dispatchEvent(intEvent); } @@ -604,11 +557,11 @@ nonTestedFunction selectOptionByLabel(id, label, fireEvent) { * @param String ID of the element to send mouseclick to * @return None */ -nonTestedFunction clickMouse (targetID) { - var localEvent = this.doc.createEvent("MouseEvents"); - localEvent.initMouseEvent("click", true, true, this.doc.defaultView, 0, 0, +function clickMouse (targetID) { + var localEvent = document.createEvent("MouseEvents"); + localEvent.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null); - this.doc.getElementById(targetID).dispatchEvent(localEvent); + document.getElementById(targetID).dispatchEvent(localEvent); } /** @@ -619,13 +572,13 @@ nonTestedFunction clickMouse (targetID) { * * @return none */ -nonTestedFunction addStuffToTextBox (id, stuff) { - var textBox = this.doc.getElementById(id); +function addStuffToTextBox (id, stuff) { + var textBox = document.getElementById(id); if (textBox.tagName.toLowerCase() === "textarea") { stuff = textBox.value ? "\n\n" + stuff : stuff; textBox.value += stuff; } else { - textBox.value = util.addCSVValue(textBox.value,stuff); + textBox.value = addCSVValue(textBox.value,stuff); } } @@ -635,9 +588,9 @@ nonTestedFunction addStuffToTextBox (id, stuff) { * @param id String with the id of the element * @param stuff String/Array with keyword(s) to be removed */ -nonTestedFunction removeStuffFromTextBox (id, stuff) { +function removeStuffFromTextBox (id, stuff) { var changedElement = this.getElementById(id); - changedElement.value = util.removeCSVValue(changedElement.value,stuff); + changedElement.value = removeCSVValue(changedElement.value,stuff); } /** @@ -647,15 +600,15 @@ nonTestedFunction removeStuffFromTextBox (id, stuff) { * @param str String to be searched for * @return Boolean found? */ -nonTestedFunction idContainsWord (id, str) { +function idContainsWord (id, str) { var kwd = ""; try { - kwd = this.doc.getElementById(id).value; + kwd = document.getElementById(id).value; } catch (e) { // For those who don't have particular element at all or if it is empty return false; } - return (util.isInList(str, kwd.trim().split(/[,\s]+/))); + return (isInList(str, kwd.trim().split(/[,\s]+/))); } /** @@ -664,19 +617,20 @@ nonTestedFunction idContainsWord (id, str) { * @param str String with the keyword * @return Boolean */ -nonTestedFunction hasKeyword (str) { - return (this.idContainsWord('keywords', str)); +function hasKeyword (str) { + return (idContainsWord('keywords', str)); } /** - -@return Element with the href attribute containng the information + * dd + * + * @return Element with the href attribute containng the information */ -nonTestedFunction getOptionTableCell(tableId, label) { - var cleanLabelRE = /^\s*([^.:]*):?\s*$/; +function getOptionTableCell(tableId, label) { + var cleanLabelRE = new RegExp("^\\s*([^.:]*):?\\s*$"); label = label.trim().replace(cleanLabelRE,"$1").toLowerCase(); - var rows = this.doc.getElementById(tableId).getElementsByTagName("tr"); + var rows = document.getElementById(tableId).getElementsByTagName("tr"); var ourLine = Array.filter(rows, function(row) { var curLabel = row.getElementsByTagName("td")[0].textContent.toLowerCase(); curLabel = curLabel.replace(cleanLabelRE,"$1"); @@ -698,18 +652,18 @@ nonTestedFunction getOptionTableCell(tableId, label) { * @todo TODO we may extend this to general setNeedinfo function * with parameter [reporter|assignee|general-email-address] */ -nonTestedFunction setNeedinfoReporter () { - this.clickMouse("needinfo"); - this.selectOption("needinfo_role", "reporter"); +function setNeedinfoReporter () { + clickMouse("needinfo"); + selectOption("needinfo_role", "reporter"); } /** * */ -nonTestedFunction getOwner () { +function getOwner () { // TODO(maemo) doesn't work on maemo - var assigneeAElement = this.getOptionTableCell("bz_show_bug_column_1","Assigned To"); - return this.parseMailto(assigneeAElement); + var assigneeAElement = getOptionTableCell("bz_show_bug_column_1","Assigned To"); + return parseMailto(assigneeAElement); } /** @@ -718,8 +672,8 @@ nonTestedFunction getOwner () { * * @return String with the maintainer's email address */ -nonTestedFunction getDefaultBugzillaMaintainer (component) { - var address = util.filterByRegexp(this.defBugzillaMaintainerArr, component); +function getDefaultBugzillaMaintainer (component) { + var address = filterByRegexp(this.defBugzillaMaintainerArr, component); return address; } @@ -731,8 +685,7 @@ nonTestedFunction getDefaultBugzillaMaintainer (component) { * string of MIME type, integer of size in kilobytes, and the whole * element itself */ - -nonTestedFunction parseAttachmentLine(inElem) { +function parseAttachmentLine(inElem) { var MIMEtype = ""; var size = 0; @@ -753,8 +706,8 @@ nonTestedFunction parseAttachmentLine(inElem) { /^.*attachment.cgi\?id=/, ""), 10); // getting MIME type and size - var stringArray = inElem.getElementsByClassName("bz_attach_extra_info")[0].textContent - .replace(/[\n ()]+/g, " ").trim().split(", "); + var stringArray = inElem.getElementsByClassName("bz_attach_extra_info")[0].textContent. + replace(/[\n ()]+/g, " ").trim().split(", "); size = parseInt(stringArray[0], 10); MIMEtype = stringArray[1].split(" ")[0]; @@ -769,12 +722,12 @@ nonTestedFunction parseAttachmentLine(inElem) { * string of MIME type, integer of size in kilobytes, and the whole * element itself */ -nonTestedFunction getAttachments () { +function getAttachments () { var outAtts = []; - var atts = this.doc.getElementById("attachment_table") - .getElementsByTagName("tr"); + var atts = document.getElementById("attachment_table"). + getElementsByTagName("tr"); for ( var i = 1, ii = atts.length - 1; i < ii; i++) { - outAtts.push(this.parseAttachmentLine(atts[i])); + outAtts.push(parseAttachmentLine(atts[i])); } return outAtts; } @@ -784,70 +737,43 @@ nonTestedFunction getAttachments () { * * @return String with the login name of the currently logged-in user */ -nonTestedFunction getLogin () { - var lastLIElement = this.doc.querySelector("#header ul.links li:last-of-type"); +function getLogin () { + var lastLIElement = document.querySelector("#header ul.links li:last-of-type"); var loginArr = lastLIElement.textContent.split("\n"); var loginStr = loginArr[loginArr.length - 1].trim(); return loginStr; } /** - * returns password from the current storage, or if there isn't - * one, then it will ask user for it. - * - * @return String with the password - */ -nonTestedFunction getPassword (login) { - var passPrompt = "Enter your Bugzilla password for fixing MIME attachment types"; - var switchPrompt = "Do you want to switch off features requiring password completely?"; - var prefName = BTSPrefNS+"withoutPassowrd"; - var domain = this.win.location.protocol + "//" + this.hostname; - - var pass = passUtils.getPassword(login, domain, BTSPassRealm); - // pass === null means no appropriate password in the storage - if (!preferences.get(prefName,false) && (pass === null)) { - var passwordText = prompts.promptPassword(passPrompt); - if (passwordText && passwordText.length > 0) { - passUtils.setLogin(login, passwordText, domain, - BTSPassRealm); - return passwordText; - } else { - var switchOff = prompts.promptYesNoCancel(switchPrompt); - if (switchOff) { - preferences.set(prefName,true); - } - return null; - } - } else { - return pass; - } -} - -/** - * + * TODO THIS IS COMPLETELY BROKEN AND NEED TO BE REWRITTEN */ -nonTestedFunction setUpLogging () { +function setUpLogging () { // Protection against double-call - if (this.doc.getElementById("generateTSButton")) { + if (document.getElementById("generateTSButton")) { return ; } + // TODO fix later + return ; // switched off for now + // For adding additional buttons to the top toolbar - var additionalButtons = this.doc.querySelector("#bugzilla-body *.related_actions"); + var additionalButtons = document.querySelector("#bugzilla-body *.related_actions"); var that = this; // logging all submits for timesheet - if (!this.submitHandlerInstalled) { - this.doc.forms.namedItem("changeform").addEventListener("submit",function (evt) { + if (!submitHandlerInstalled) { + document.forms.namedItem("changeform").addEventListener("submit",function (evt) { + // TODO this is probably another RPC call var resp = that.log.addLogRecord(that); if (resp === null) { evt.stopPropagation(); evt.preventDefault(); } }, false); - this.submitHandlerInstalled = true; + submitHandlerInstalled = true; } + // TODO another RPC call // (id, text, parent, callback, params, before, covered, accesskey) this.createDeadLink("generateTSButton", "Generate TS", additionalButtons, function(evt) { @@ -855,18 +781,20 @@ nonTestedFunction setUpLogging () { that.log.generateTimeSheet); }, [], "dash", "li"); + // TODO another RPC call this.createDeadLink("clearLogs", "Clear TS", additionalButtons, function(evt) { that.log.clearStore(this); }, [], "dash", "li"); + // TODO another RPC call this.createDeadLink("importTSButton", "Import TS", additionalButtons, function(evt) { jsonPaths = prompts.promptFileOpenPicker(that.win); that.log.importOtherStore(jsonPaths, clearLogAElem); }, [], "dash", "li"); - var clearLogAElem = this.doc.getElementById("clearLogs"); + var clearLogAElem = document.getElementById("clearLogs"); if (this.log.isEmpty()) { clearLogAElem.style.color = this.log.EmptyLogsColor; clearLogAElem.style.fontWeight = "normal"; @@ -876,10 +804,11 @@ nonTestedFunction setUpLogging () { } } -nonTestedFunction getSelectionOrClipboard () { - var text = selection.text; - if (!text) { - text = clip.get(); +function getSelection () { + var text = ""; + var selectionObject = window.getSelection(); + if (selectionObject.rangeCount > 0) { + text = selectionObject.getRangeAt(0).toString(); } return text; } @@ -894,8 +823,8 @@ nonTestedFunction getSelectionOrClipboard () { * @return None * */ -nonTestedFunction queryInNewTab(text, component, product) { - var urlStr = "https://bugzilla.redhat.com/buglist.cgi?query_format=advanced"; +function queryInNewTab(text, component, product) { + var urlStr = "https://" + window.location.hostname + "/buglist.cgi?query_format=advanced"; if (product) { urlStr += "&product=" + product.trim(); } @@ -928,13 +857,7 @@ nonTestedFunction queryInNewTab(text, component, product) { + "&field1-0-2=status_whiteboard&type1-0-2=substring&value1-0-2=" + text; urlStr += searchText; - tabs.open({ - url: urlStr, - inBackground: true, - onReady: function (t) { - t.activate(); - } - }); + postMessage(new Message("OpenURLinNewTab", urlStr)); } } @@ -942,10 +865,12 @@ nonTestedFunction queryInNewTab(text, component, product) { * Get the text to search for and prepare other things for the real executive * function this.queryInNewTab, and run it. */ -nonTestedFunction queryForSelection() { - var text = this.getSelectionOrClipboard(); - if (text) { - this.queryInNewTab(text, this.getComponent()); +function queryForSelection() { + var text = getSelection(); + if (!text) { + postMessage(new Message("GetClipboard", "queryLocal")); + } else { + queryInNewTab(text, getComponent(), getProduct()); } } @@ -955,16 +880,16 @@ nonTestedFunction queryForSelection() { * @param who String with email address or "self" if the current user * of the bugzilla should be added */ -nonTestedFunction addToCCList (who) { +function addToCCList (who) { if (!who) { return ; } if (who === "self") { - this.doc.getElementById("addselfcc").checked = true; + document.getElementById("addselfcc").checked = true; } else { - this.clickMouse("cc_edit_area_showhide"); - if (!util.isInList(who, this.CCList)) { - this.addStuffToTextBox("newcc",who); + clickMouse("cc_edit_area_showhide"); + if (!isInList(who, getCCList())) { + addStuffToTextBox("newcc",who); } } } @@ -974,8 +899,8 @@ nonTestedFunction addToCCList (who) { * * @return Array with email addresses as Strings. */ -nonTestedFunction getCCList () { - var CCListSelect = this.doc.getElementById("cc"); +function getCCList () { + var CCListSelect = document.getElementById("cc"); var outCCList = []; if (CCListSelect) { outCCList = Array.map(CCListSelect.options, function(item) { @@ -985,106 +910,28 @@ nonTestedFunction getCCList () { return outCCList; } -// exports.BZPage = apiUtils.publicConstructor(BZPage); -// BZPage's methods -var BZPage = function BZPage(win, config) { - // constants - this.SalmonPink = new Color(255, 224, 176); // RGB 255, 224, 176; HSL 36, 2, - // 85 - this.ReporterColor = new Color(255, 255, 166); // RGB 255, 255, 166; HSL 60, 2, - // 83 - - // initialize dynamic properties - var that = this; - this.win = win; - this.doc = win.document; - this.hostname = this.win.location.hostname; - +function startup() { // First, preflight check ... if we are not logged in, there // is nothing we can do. - var logoutLink = Array.some(this.doc.links, function (x) { + var logoutLink = Array.some(document.links, function (x) { return x.search === "?logout=1" ; }); if (!logoutLink) { - throw new NotLoggedinException("Not logged in"); + return null; // This should just finish whole content script without + // doing any harm to anybody. } + // TODO Probably could be ignored ... used only once on line 973 of rhbzpage.js + // if (parseAbrtBacktraces && this.RE.Abrt.test(this.title)) { + this.title = document.getElementById("short_desc_nonedit_display").textContent; + // So, now we know we are logged in, so we can get to // the real work. - this.packages = this.getInstalledPackages(config); - - if ("commentStrings" in config.gJSONData) { - this.commentStrings = config.gJSONData.commentStrings; - } - - this.constantData = {}; - if ("constantData" in config.gJSONData) { - this.constantData = config.gJSONData.constantData; - this.constantData.queryUpstreamBug = JSON.parse( - selfMod.data.load("queryUpstreamBug.json")); - this.constantData.XMLRPCData = JSON.parse( - selfMod.data.load("XMLRPCdata.json")); - } - - if ("CCmaintainer" in this.constantData) { - this.defBugzillaMaintainerArr = this.constantData.CCmaintainer; - } - - if ("suspiciousComponents" in config.gJSONData.configData) { - this.suspiciousComponents = config.gJSONData.configData.suspiciousComponents; - } - - if ("XorgLogAnalysis" in config.gJSONData.configData) { - this.xorglogAnalysis = config.gJSONData.configData.XorgLogAnalysis; - } + setConfigurationButton(); + submitHandlerInstalled = false; - if ("submitsLogging" in config.gJSONData.configData && - config.gJSONData.configData.submitsLogging) { - this.log = config.logger; - this.setUpLogging(); - } - - if ("killNodes" in config.gJSONData.configData && - this.hostname in config.gJSONData.configData.killNodes) { - var killConf = config.gJSONData.configData.killNodes[this.hostname]; - util.killNodes(this.doc, killConf[0], killConf[1]); - } - - this.setConfigurationButton(); - this.submitHandlerInstalled = false; - - this.login = this.getLogin(); - // XML-RPC password - if (this.hostname in this.constantData.XMLRPCData) { - this.password = this.getPassword(this.login); - } - - this.bugNo = util.getBugNo(this.doc.location.toString()); + checkComments(); - // deal with aliases - if (isNaN(parseInt(this.bugNo, 10)) && this.password) { - this.bugNo = this.getRealBugNo(); - } - - this.title = this.doc.getElementById("short_desc_nonedit_display").textContent; - this.CCList = this.getCCList(); - - // 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 = this.doc.getElementsByName("add_comment")[0].parentNode; - if (commentArea) { - var brElementPlacer = commentArea.getElementsByTagName("br"); - brElementPlacer = brElementPlacer[0]; - if (brElementPlacer) { - brElementPlacer.setAttribute("id","brElementPlacer_location"); - brElementPlacer.parentNode.insertBefore(this.doc.createElement("br"), - brElementPlacer); - } - } - - this.checkComments(); - this.generateButtons(); -}; + var login = getLogin(); + postMessage(new Message("GetInstalledPackages", window.location)); +} diff --git a/lib/color.js b/data/color.js index 574ad19..574ad19 100644 --- a/lib/color.js +++ b/data/color.js diff --git a/data/rhbzpage.js b/data/rhbzpage.js index 1d0907a..ba55ed6 100644 --- a/data/rhbzpage.js +++ b/data/rhbzpage.js @@ -104,6 +104,19 @@ nonTestedFunction addAttachment(data, callback, param) { var msg = new xrpc.XMLRPCMessage("bugzilla.addAttachment"); var that = this; + // Get bug no + var bugNo = getBugNo(window.location.toString()); + + // deal with aliases + // FIXME there is no password in content scripts anymore! + if (isNaN(parseInt(bugNo, 10)) && this.password) { + getRealBugNo(function(bugN) { + // Zbytek funkce addAttachment + }); + } + + + msg.addParameter(this.bugNo); msg.addParameter({ description: titleParsedAttachment, @@ -119,7 +132,7 @@ nonTestedFunction addAttachment(data, callback, param) { url: this.constantData.XMLRPCData[this.hostname].url, onComplete: function(response) { if (response.status == 200) { - var resp = util.parseXMLfromString(response.text); + var resp = parseXMLfromString(response.text); var newAttachID = parseInt(resp.params.param.value.array.data.value.int, 10); console.log("attachID = " + newAttachID); callback.call(that, param, newAttachID, data.length); @@ -310,6 +323,7 @@ nonTestedFunction addCheckShowLink(oldAtt, snippet) { nonTestedFunction markBadAttachments(atts) { var that = this; var badMIMEArray = [ "application/octet-stream", "text/x-log", "undefined" ]; + // FIXME there is no password anymore, we have to fix it somehow else if (!this.password) { return ; // User didn't provide password, so whole MIME fixing business // should be switched off. @@ -414,7 +428,7 @@ nonTestedFunction setBranding() { } // we should make visible whether maintCCAddr is in CCList - if (util.isInList(this.maintCCAddr, this.CCList)) { + if (util.isInList(this.maintCCAddr, getCCList())) { var ccEditBoxElem = this.doc.getElementById("cc_edit_area_showhide"); ccEditBoxElem.style.color = "navy"; ccEditBoxElem.style.fontWeight = "bolder"; @@ -619,9 +633,10 @@ nonTestedFunction fillInChipMagic() { // Persuade createNewButton to have mercy and to actually add // non-default button that.constantData.chipMagicTrigger = true; - that.packages["rh-xorg"].chipMagic.chipMagic = interestingLine+"\t"+interestingArray[1] - .toUpperCase(); - that.createNewButton("status_whiteboard", true, "rh-xorg", "chipMagic"); + // FIXME packages don't exist anymore + // that.packages["rh-xorg"].chipMagic.chipMagic = interestingLine+"\t"+interestingArray[1] + // .toUpperCase(); + createNewButton("status_whiteboard", true, "rh-xorg", "chipMagic"); } } } @@ -706,6 +721,7 @@ nonTestedFunction XMLRPCcallback() { } } +// FIXME this whole goes to libbzpage.js /** * The worker function -- call XMLRPC to fix MIME type of the particular * attachment diff --git a/lib/util.js b/data/util.js index 4612b66..4612b66 100644 --- a/lib/util.js +++ b/data/util.js diff --git a/lib/libbugzilla.js b/lib/libbugzilla.js new file mode 100644 index 0000000..ceea270 --- /dev/null +++ b/lib/libbugzilla.js @@ -0,0 +1,273 @@ +/*jslint rhino: true, forin: true, onevar: false, browser: true, evil: true, laxbreak: true, undef: true, nomen: true, eqeqeq: false, bitwise: true, maxerr: 1000, immed: false, white: false, plusplus: false, regexp: false, undef: false */ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php +// +"use strict"; +var preferences = require("preferences-service"); +var prompts = require("prompts"); +var clipboard = require("clipboard"); +var tabs = require("tabs"); +var logger = require("logger"); +var passUtils = require("passwords"); +var Request = require("request").Request; + +var JSONURLDefault = "https://fedorahosted.org/released"+ + "/bugzilla-triage-scripts/Config_data.json"; +var BTSPrefNS = "bugzilla-triage.setting."; +var BTSPassRealm = "BTSXMLRPCPass"; + +var config = {}; + +/** + * parse XML object out of string working around various bugs in Gecko implementation + * see https://developer.mozilla.org/en/E4X for more information + * + * @param inStr String with unparsed XML string + * @return XML object + */ +function parseXMLfromString (inStuff) { + // if (typeof inStuff !== 'string') In future we should recognize this.response + // and get just .text property out of it. TODO + var respStr = inStuff.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, ""); // bug 336551 + return new XML(respStr); +} + +/** + * In case URL contains alias, not the real bug number, get the real bug no + * from the XML representation. Sets correct value to this.bugNo. + * + * somewhere in RPC functions which need it, we should have + * if (isNAN(parseInt(bugNo, 10))) { + * getRealBugNo(bugNo, location, callback); + * } + * Or not + */ +function getRealBugNo(bugNo, location, callback) { + console.log("We have to deal with bug aliased as " + this.bugNo); + // https://bugzilla.redhat.com/show_bug.cgi?ctype=xml&id=serialWacom + Request({ + url: location.href+"&ctype=xml", + onComplete: function(response) { + if (response.status === 200) { + var xmlRepr = parseXMLfromString(response.text); + // TODO this is probably wrong, both XPath and .text attribute + var bugID = parseInt(xmlRepr.bug.bug_id.text, 10); + if (isNaN(bugID)) { + throw new Error("Cannot get bug no. even from XML representation!"); + } + console.log("The real bug no. is " + bugID); + callback(bugID) + } + } + }).get(); +} + +exports.getPassword = function getPassword(login, domain, callback) { + var passPrompt = "Enter your Bugzilla password for fixing MIME attachment types"; + var switchPrompt = "Do you want to switch off features requiring password completely"; + var prefName = BTSPrefNS+"withoutPassowrd"; + var domain = window.location.protocol + "//" + window.location.hostname; + + var pass = passUtils.getPassword(login, + domain, BTSPassRealm); + var retObject = { + password: null, + withoutPass: false + }; + + // pass === null means no appropriate password in the storage + if (!preferences.get(prefName,false) && (pass === null)) { + passwordText = prompts.promptPassword(passPrompt); + if (passwordText && passwordText.length > 0) { + passUtils.setLogin(login, passwordText, domain, + BTSPassRealm); + retObject.password = passwordText; + } else { + var switchOff = prompts.promptYesNoCancel(switchPrompt); + if (switchOff) { + preferences.set(prefName,true); + } + retObject.withoutPass = switchOff; + } + } else { + retObject.password = pass; + } + callback(new Message("RetPassword", retObject)); +}; + +exports.changeJSONURL = function changeJSONURL() { + var prfNm = BTSPrefNS+"JSONURL"; + var url = preferences.get(prfNm,""); + + var reply = prompts.prompt("New location of JSON configuration file", url); + if (reply) { + preferences.set(prfNm, reply.trim()); + // TODO Restartless add-on needs to resolve this. + prompts.alert("For now, you should really restart Firefox!"); + } +}; + +/** + * + libbz.getInstalledPackages(msg.data, function (pkgsMsg) { + worker.postMessage(pkgsMsg); + */ +exports.getInstalledPackages = function getInstalledPackages(location, callback) { + var installedPackages = {}; + var enabledPackages = []; + + // Collect enabled packages per hostname (plus default ones) + if (config.gJSONData && ("commentPackages" in config.gJSONData)) { + if ("enabledPackages" in config.gJSONData.configData) { + var epObject = config.gJSONData.configData.enabledPackages; + if (location.hostname in epObject) { + enabledPackages = enabledPackages.concat(epObject[location.hostname].split(/[,\s]+/)); + } + if ("any" in epObject) { + enabledPackages = enabledPackages.concat(epObject.any.split(/[,\s]+/)); + } + } + + if ((enabledPackages.length === 1) && (enabledPackages[0] === "all")) { + enabledPackages = []; + for (var key in config.gJSONData.commentPackages) { + enabledPackages.push(key); + } + } + + // TODO To be decided, whether we cannot just eliminate packages in + // installedPackages and having it just as a plain list of all cmdObjects. + enabledPackages.forEach(function (pkg, idx, arr) { + if (pkg in config.gJSONData.commentPackages) { + installedPackages[pkg] = config.gJSONData.commentPackages[pkg]; + } + }); + } + + // Expand commentIdx properties into full comments + installedPackages.forEach(function (pkg) { + pkg.forEach(function (cmdObj) { + if ("commentIdx" in cmdObj) { + cmdObj.comment = config.commentStrings[cmdObj.commentIdx]; + delete cmdObj.commentIdx; + } + }); + }); + callback(new Message("CreateButtons", { + instPkgs: installedPackages, + constData: config.constantData + })); +}; + +exports.getClipboard = function getClipboard(command, cb) { + cb(new Message("RetClipboard", { + text: clipboard.get(), + cmd: command + })); +}; + +exports.openURLinNewTab = function openURLinNewTab(urlStr) { + tabs.open({ + url: urlStr, + inBackground: true, + onReady: function (t) { + t.activate(); + } + }); +}; + +function initialize() { + var prefName = BTSPrefNS+"JSONURL"; + var urlStr = ""; + + if (preferences.isSet(prefName)) { + urlStr = preferences.get(prefName); + } else { + urlStr = JSONURLDefault; + preferences.set(prefName, JSONURLDefault); + } + + // Randomize URL to avoid caching + // TODO see https://fedorahosted.org/bugzilla-triage-scripts/ticket/21 + // for more thorough discussion and possible further improvement + urlStr += (urlStr.match(/\?/) == null ? "?" : "&") + (new Date()).getTime(); + + Request({ + url: urlStr, + onComplete: function (response) { + if (response.status == 200) { + config.gJSONData = response.json; + + // Get additional tables + if ("downloadJSON" in config.gJSONData.configData) { + var URLsList = config.gJSONData.configData.downloadJSON; + var dwnldObj = ""; + URLsList.forEach(function (arr) { + var title = arr[0]; + var url = arr[1]; + Request({ + url: url, + onComplete: function(response) { + if (response.status == 200) { + config.gJSONData.constantData[title] = response.json; + } + } + }).get(); + }); + } + + config.logger = new logger.Logger(JSON.parse(self.data.load("bugzillalabelAbbreviations.json"))); + + config.matches = config.gJSONData.configData.matches; + config.skipMatches = config.matches.map(function(x) { + return x.replace("show_bug.cgi.*","((process|post)_bug|attachment)\.cgi$"); + }); + + config.objConstructor = {}; + // var bzType = config.gJSONData.configData.objectStyle; + // if (bzType === "RH") { + // config.objConstructor = require("rhbzpage").RHBugzillaPage; + // } else if (bzType === "MoFo") { + // } + // config.objConstructor = require("mozillabzpage").MozillaBugzilla; + + // callback(config); + + config.constantData = {}; + // TODO this is important and missing + if ("constantData" in config.gJSONData) { + config.constantData = config.gJSONData.constantData; + config.constantData.queryUpstreamBug = JSON.parse( + selfMod.data.load("queryUpstreamBug.json")); + config.constantData.XMLRPCData = JSON.parse( + selfMod.data.load("XMLRPCdata.json")); + } + + if ("CCmaintainer" in config.constantData) { + config.defBugzillaMaintainerArr = config.constantData.CCmaintainer; + } + + if ("suspiciousComponents" in config.gJSONData.configData) { + config.suspiciousComponents = config.gJSONData.configData.suspiciousComponents; + } + + if ("XorgLogAnalysis" in config.gJSONData.configData) { + config.xorglogAnalysis = config.gJSONData.configData.XorgLogAnalysis; + } + + if ("submitsLogging" in config.gJSONData.configData && + config.gJSONData.configData.submitsLogging) { + config.log = config.logger; + // FIXME this.setUpLogging(); + } + + if ("killNodes" in config.gJSONData.configData && + window.location.hostname in config.gJSONData.configData.killNodes) { + var killConf = config.gJSONData.configData.killNodes[window.location.hostname]; + util.killNodes(config.doc, killConf[0], killConf[1]); + } + + } + } + }).get(); +} diff --git a/lib/main.js b/lib/main.js index 35d7d60..cbb3ba6 100644 --- a/lib/main.js +++ b/lib/main.js @@ -11,18 +11,11 @@ // http://ehsanakhgari.org/blog/2010-05-31/my-experience-jetpack-sdk#comment-1253 // "use strict"; -var logger = require("logger"); var browser = require("tab-browser"); var self = require("self"); var Request = require("request").Request; -var preferences = require("preferences-service"); var pageMod = require("page-mod"); -// var BTSPrefNS = require("bzpage").BTSPrefNS; -// Use my JSON for now before it is fixed for general public -var JSONURLDefault = "https://fedorahosted.org/released"+ - "/bugzilla-triage-scripts/Config_data.json"; - -var config = {}; +var libbz = require("libbugzilla"); function isOurPage(window, matchingURLs) { var url = window.location.href; @@ -48,66 +41,6 @@ function skipThisPage(doc) { } } -function initialize(callback) { - var prefName = BTSPrefNS+"JSONURL"; - var urlStr = ""; - - if (preferences.isSet(prefName)) { - urlStr = preferences.get(prefName); - } else { - urlStr = JSONURLDefault; - preferences.set(prefName, JSONURLDefault); - } - - // Randomize URL to avoid caching - // TODO see https://fedorahosted.org/bugzilla-triage-scripts/ticket/21 - // for more thorough discussion and possible further improvement - urlStr += (urlStr.match(/\?/) == null ? "?" : "&") + (new Date()).getTime(); - - Request({ - url: urlStr, - onComplete: function (response) { - if (response.status == 200) { - config.gJSONData = response.json; - - // Get additional tables - if ("downloadJSON" in config.gJSONData.configData) { - var URLsList = config.gJSONData.configData.downloadJSON; - var dwnldObj = ""; - URLsList.forEach(function (arr) { - var title = arr[0]; - var url = arr[1]; - Request({ - url: url, - onComplete: function(response) { - if (response.status == 200) { - config.gJSONData.constantData[title] = response.json; - } - } - }).get(); - }, this); - } - - config.logger = new logger.Logger(JSON.parse(self.data.load("bugzillalabelAbbreviations.json"))); - - config.matches = config.gJSONData.configData.matches; - config.skipMatches = config.matches.map(function(x) { - return x.replace("show_bug.cgi.*","((process|post)_bug|attachment)\.cgi$"); - }); - - config.objConstructor = {}; - var bzType = config.gJSONData.configData.objectStyle; - if (bzType === "RH") { - config.objConstructor = require("rhbzpage").RHBugzillaPage; - } else if (bzType === "MoFo") { - config.objConstructor = require("mozillabzpage").MozillaBugzilla; - } - - callback(config); - } - } - }).get(); -} /* exports.main = function main(options, callbacks) { @@ -141,28 +74,25 @@ var messageHandler = exports.messageHandler = function messageHandler(worker, ms case "LogMessage": console.log(msg.data); break; - case "GetDuplicatorID": - getDuplicatorID(msg.data.host, msg.data.bugID, function (msgObj) { - worker.postMessage(msgObj); + case "ExecCmd": + libbz.executeCommand(msg.data); + break; + case "GetInstalledPackages": + // send message with packages back + libbz.getInstalledPackages(msg.data, function (pkgsMsg) { + worker.postMessage(pkgsMsg); }); break; - case "GetPassword": - getPassword(msg.data.login, msg.data.hostname, function (pass) { - worker.postMessage(pass); + case "GetClipboard": + libbz.getClipboard(msg.data, function (clipboard) { + worker.postMessage(clipboard); }); break; - case "DeDeduplicateQueue": - LoginData = { - queue: msg.data.bugs, - host: msg.data.hostname, - login: msg.data.login, - pass: msg.data.password, - dupID: msg.data.duplicator, - finalCallback: function (msgObj) { - worker.postMessage(msgObj); - } - }; - processReqQueue(); + case "ChangeJSONURL": + libbz.changeJSONURL(); + break; + case "OpenURLinNewTab": + libbz.openURLinNewTab(msg.data); break; case "testReady": // we ignore it here, interesting only in unit test @@ -174,6 +104,8 @@ var messageHandler = exports.messageHandler = function messageHandler(worker, ms var contentScriptLibraries = { "bugzilla.redhat.com": [ + self.data.url("util.js"), + self.data.url("color.js"), self.data.url("bzpage.js"), self.data.url("rhbzpage.js") ] |