diff options
-rw-r--r-- | data/lib/addAttachmentRow.js | 41 | ||||
-rw-r--r-- | data/lib/bugzillaDOMFunctions.js | 372 | ||||
-rw-r--r-- | data/lib/bzpage.js | 345 | ||||
-rw-r--r-- | data/lib/fixingAttMIME.js | 87 | ||||
-rw-r--r-- | data/lib/makeBacktraceAttachment.js | 157 | ||||
-rw-r--r-- | data/lib/otherButtons.js | 8 | ||||
-rw-r--r-- | data/lib/queries.js | 34 | ||||
-rw-r--r-- | data/lib/rhbzpage.js | 369 | ||||
-rw-r--r-- | data/lib/util.js | 13 | ||||
-rw-r--r-- | lib/main.js | 5 |
10 files changed, 720 insertions, 711 deletions
diff --git a/data/lib/addAttachmentRow.js b/data/lib/addAttachmentRow.js new file mode 100644 index 0000000..13ad226 --- /dev/null +++ b/data/lib/addAttachmentRow.js @@ -0,0 +1,41 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php +"use strict"; + +function addAttachmentCallback(resp) { + var newAttachID = parseInt(resp.params.param.value.array.data.value.int, 10); + console.log("attachID = " + newAttachID); + // FIXME callback.call(param, newAttachID, data.length); +} + +/** + * + * This has to stay in RHBugzillaPage because upstream doesn't have addAttachment + * XML-RPC call yet. + */ +function addAttachment(data, callback, param) { + var params = []; + + if (!constantData.passwordState.passAvailable) { + console.error("addAttachment : No password, no XML-RPC calls; sorry"); + return null; + } + + params.push(getBugNo()); + params.push({ + description: titleParsedAttachment, + filename: "parsed-backtrace.txt", + contenttype: "text/plain", + data: window.btoa(data), + nomail: true + }); + + postMessage(new Message("MakeXMLRPCall", { + url: constantData.XMLRPCData[window.location.hostname].url, + login: getLogin(), + method: "bugzilla.addAttachment", + params: params, + callRPC: "AddAttachmentCallback" + })); + reqCounter++; +} diff --git a/data/lib/bugzillaDOMFunctions.js b/data/lib/bugzillaDOMFunctions.js new file mode 100644 index 0000000..30405f0 --- /dev/null +++ b/data/lib/bugzillaDOMFunctions.js @@ -0,0 +1,372 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php +"use strict"; + +/** + * Select option with given value on the <SELECT> element with given id. + * + * Also execute change HTMLEvent, so that the form behaves accordingly. + * + * @param id + * @param label + * @return none + * + */ +function selectOption (id, label, fireEvent) { + if (!fireEvent) { + fireEvent = true; + } + var sel = document.getElementById(id); + sel.value = label; + if (fireEvent) { + var intEvent = document.createEvent("HTMLEvents"); + intEvent.initEvent("change", true, true); + sel.dispatchEvent(intEvent); + } +} + +function selectOptionByLabel(id, label, fireEvent) { + if (!fireEvent) { + fireEvent = true; + } + var sel = document.getElementById(id); + var labelRE = new RegExp(label.trim()); + var ourOption = Array.filter(sel.options, function (op) { + return op.textContent.trim() === label; + }); + + if (ourOption[0]) { + sel.value = ourOption[0].value; + } + + if (fireEvent) { + var intEvent = document.createEvent("HTMLEvents"); + intEvent.initEvent("change", true, true); + sel.dispatchEvent(intEvent); + } +} + +/** + * Add object to the text box (comment box or status whiteboard) + * + * @param id String with the id of the element + * @param stuff String/Array to be added to the comment box + * + * @return none + */ +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 = addCSVValue(textBox.value,stuff); + } +} + +/** + * Remove a keyword from the element if it is there + * + * @param id String with the id of the element + * @param stuff String/Array with keyword(s) to be removed + */ +function removeStuffFromTextBox (id, stuff) { + var changedElement = document.getElementById(id); + changedElement.value = removeCSVValue(changedElement.value,stuff); +} + +/** + * generalized hasKeyword ... search in the value of the box with given id + * + * @param id String with ID of the element we want to check + * @param str String to be searched for + * @return Boolean found? + */ +function idContainsWord (id, str) { + var kwd = ""; + try { + 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 (isInList(str, kwd.trim().split(/[,\s]+/))); +} + +/** + * Check for the presence of a keyword + * + * @param str String with the keyword + * @return Boolean + */ +function hasKeyword (str) { + return (idContainsWord('keywords', str)); +} + +/** + * Set the bug to NEEDINFO state + * + * Working function. + * @return none + * @todo TODO we may extend this to general setNeedinfo function + * with parameter [reporter|assignee|general-email-address] + */ +function setNeedinfoReporter () { + clickMouse("needinfo"); + selectOption("needinfo_role", "reporter"); +} + +/** + * + */ +function getOwner () { + // TODO(maemo) doesn't work on maemo + var assigneeAElement = getOptionTableCell("bz_show_bug_column_1","Assigned To"); + return parseMailto(assigneeAElement); +} + +/** + * Return maintainer which is per default by bugzilla + * (which is not necessarily the one who is default maintainer per component) + * + * @return String with the maintainer's email address + */ +function getDefaultBugzillaMaintainer (component) { + var address = filterByRegexp(constantData.defBugzillaMaintainerArr, component); + return address; +} + +/** + * 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 location Object around which the new button will be added + * @param after Boolean before or after location ? + * @param pkg String which package to take the command from + * @param id String which command to take + * @return none + */ +function createNewButton (location, after, cmdObj) { + try { + var newId = cmdObj.name.toLowerCase().replace(/[^a-z0-9]+/,"","g") + "_btn"; + } catch (e) { + console.error("createNewButton : e = " + e + + "\ncreateNewButton : cmdObj.toSource() = " + + cmdObj.toSource()); + } + + // protection against double-firings + if (document.getElementById(newId)) { + console.log("Element with id " + newId + " already exists!"); + return ; + } + + var newButton = document.createElement("input"); + newButton.setAttribute("id", newId); + newButton.setAttribute("type", "button"); + newButton.value = cmdObj.name; + newButton.addEventListener("click", function(evt) { + executeCommand(cmdObj); + }, false); + + var originalLocation = document.getElementById(location); + + try { + if (after) { + originalLocation.parentNode.insertBefore(newButton, + originalLocation.nextSibling); + originalLocation.parentNode.insertBefore(document + .createTextNode("\u00A0"), newButton); + } + else { + originalLocation.parentNode.insertBefore(newButton, originalLocation); + originalLocation.parentNode.insertBefore(document + .createTextNode("\u00A0"), originalLocation); + } + } catch (e) { + if (e instanceof TypeError) { + console.error("cannot find originalLocation element with id " + location); + } + else { + throw e; + } + } +} + +/** + * Get the current title of the bug + * + * @return string + */ +function getSummary() { + return document.getElementById("short_desc_nonedit_display").textContent; +} + +/** + * Get the current email of the reporter of the bug. + * + * @return string + */ +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 = 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 parseMailto(reporterElement); +} + +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; +} + +function commentsWalker (fce) { + var comments = document.getElementById("comments"). + getElementsByClassName("bz_comment"); + Array.forEach(comments, function(item) { + fce(item); + }); +} + +/** + * collect the list of attachments in a structured format + * + * @return Array of arrays, one for each attachments; + * each record has string name of the attachment, integer its id number, + * string of MIME type, integer of size in kilobytes, and the whole + * element itself + */ +function getAttachments () { + var outAtts = []; + var atts = document.getElementById("attachment_table"). + getElementsByTagName("tr"); + for ( var i = 1, ii = atts.length - 1; i < ii; i++) { + outAtts.push(parseAttachmentLine(atts[i])); + } + return outAtts; +} + +/** + * Get login of the currently logged-in user. + * + * @return String with the login name of the currently logged-in user + */ +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; +} + +/** + * adds a person to the CC list, if it isn't already there + * + * @param who String with email address or "self" if the current user + * of the bugzilla should be added + */ +function addToCCList (who) { + if (!who) { + return ; + } + if (who === "self") { + document.getElementById("addselfcc").checked = true; + } + else { + clickMouse("cc_edit_area_showhide"); + if (!isInList(who, getCCList())) { + addStuffToTextBox("newcc",who); + } + } +} + +/** + * a collect a list of emails on CC list + * + * @return Array with email addresses as Strings. + */ +function getCCList () { + var CCListSelect = document.getElementById("cc"); + var outCCList = []; + if (CCListSelect) { + outCCList = Array.map(CCListSelect.options, function(item) { + return item.value; + }); + } + return outCCList; +} + +/** + * remove elements from the page based on their IDs + * + * @param doc Document object + * @param target String/Array with ID(s) + * @param remove Boolean indicating whether the node should be + * actually removed or just hidden. + * @return none + * TODO remove parameter could be replaced by function which would + * do actual activity. + */ +function killNodes(doc, target, remove) { + var targetArr = target instanceof Array ? target : target.trim().split(/[,\s]+/); + targetArr.forEach(function(x) { + if (remove) { + var targetNode = doc.getElementById(x); + targetNode.parentNode.removeChild(targetNode); + } + else { + x.style.display = "none"; + } + }); +} + +/** + * Is this bug a RHEL bug? + * + * @return Boolean true if it is a RHEL bug + */ +function isEnterprise() { + var result = ProfessionalProducts.some(function(elem,idx,arr) { + return new RegExp(elem).test(getProduct()); + }); + return result; +} + +/** + * Find out whether the bug is needed an attention of bugZappers + * + * @return Boolean whether the bug has been triaged or not + */ +function isTriaged() { + return hasKeyword("Triaged"); +} + +/** + * 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, bzLabelNames) { + var bugzillaID = ""; + if (bzLabelNames[URLhostname]) { + bugzillaID = bzLabelNames[URLhostname]; + } + else { + bugzillaID = ""; + } + return bugzillaID; +} diff --git a/data/lib/bzpage.js b/data/lib/bzpage.js index 87030e4..d65c232 100644 --- a/data/lib/bzpage.js +++ b/data/lib/bzpage.js @@ -179,30 +179,6 @@ function centralCommandDispatch (cmdLabel, cmdParams) { } /** - * remove elements from the page based on their IDs - * - * @param doc Document object - * @param target String/Array with ID(s) - * @param remove Boolean indicating whether the node should be - * actually removed or just hidden. - * @return none - * TODO remove parameter could be replaced by function which would - * do actual activity. - */ -function killNodes(doc, target, remove) { - var targetArr = target instanceof Array ? target : target.trim().split(/[,\s]+/); - targetArr.forEach(function(x) { - if (remove) { - var targetNode = doc.getElementById(x); - targetNode.parentNode.removeChild(targetNode); - } - else { - x.style.display = "none"; - } - }); -} - -/** * Change assignee of the bug * * @param newAssignee String with the email address of new assigneeAElement @@ -280,63 +256,6 @@ function addToCommentsDropdown (cmdObj) { } /** - * 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 location Object around which the new button will be added - * @param after Boolean before or after location ? - * @param pkg String which package to take the command from - * @param id String which command to take - * @return none - */ -function createNewButton (location, after, cmdObj) { - try { - var newId = cmdObj.name.toLowerCase().replace(/[^a-z0-9]+/,"","g") + "_btn"; - } catch (e) { - console.error("createNewButton : e = " + e + - "\ncreateNewButton : cmdObj.toSource() = " + - cmdObj.toSource()); - } - - // protection against double-firings - if (document.getElementById(newId)) { - console.log("Element with id " + newId + " already exists!"); - return ; - } - - var newButton = document.createElement("input"); - newButton.setAttribute("id", newId); - newButton.setAttribute("type", "button"); - newButton.value = cmdObj.name; - newButton.addEventListener("click", function(evt) { - executeCommand(cmdObj); - }, false); - - var originalLocation = document.getElementById(location); - - try { - if (after) { - originalLocation.parentNode.insertBefore(newButton, - originalLocation.nextSibling); - originalLocation.parentNode.insertBefore(document - .createTextNode("\u00A0"), newButton); - } - else { - originalLocation.parentNode.insertBefore(newButton, originalLocation); - originalLocation.parentNode.insertBefore(document - .createTextNode("\u00A0"), originalLocation); - } - } catch (e) { - if (e instanceof TypeError) { - console.error("cannot find originalLocation element with id " + location); - } - else { - throw e; - } - } -} - -/** * Generate button based on */ function generateButtons (pkgs, kNodes) { @@ -406,54 +325,6 @@ function setConfigurationButton () { } /** - * Get the current title of the bug - * - * @return string - */ -function getSummary() { - return document.getElementById("short_desc_nonedit_display").textContent; -} - -/** - * Get the current email of the reporter of the bug. - * - * @return string - */ -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 = 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 parseMailto(reporterElement); -} - -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; -} - -function commentsWalker (fce) { - var comments = document.getElementById("comments"). - getElementsByClassName("bz_comment"); - Array.forEach(comments, function(item) { - fce(item); - }); -} - -/** * Set background color of all comments made by reporter in ReporterColor color * */ @@ -476,122 +347,6 @@ function collectComments () { return outStr.trim(); } - -/** - * Select option with given value on the <SELECT> element with given id. - * - * Also execute change HTMLEvent, so that the form behaves accordingly. - * - * @param id - * @param label - * @return none - * - */ -function selectOption (id, label, fireEvent) { - if (!fireEvent) { - fireEvent = true; - } - var sel = document.getElementById(id); - sel.value = label; - if (fireEvent) { - var intEvent = document.createEvent("HTMLEvents"); - intEvent.initEvent("change", true, true); - sel.dispatchEvent(intEvent); - } -} - -function selectOptionByLabel(id, label, fireEvent) { - if (!fireEvent) { - fireEvent = true; - } - var sel = document.getElementById(id); - var labelRE = new RegExp(label.trim()); - var ourOption = Array.filter(sel.options, function (op) { - return op.textContent.trim() === label; - }); - - if (ourOption[0]) { - sel.value = ourOption[0].value; - } - - if (fireEvent) { - var intEvent = document.createEvent("HTMLEvents"); - intEvent.initEvent("change", true, true); - sel.dispatchEvent(intEvent); - } -} - -/** - * Send mouse click to the specified element - * - * @param String ID of the element to send mouseclick to - * @return None - */ -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); - document.getElementById(targetID).dispatchEvent(localEvent); -} - -/** - * Add object to the text box (comment box or status whiteboard) - * - * @param id String with the id of the element - * @param stuff String/Array to be added to the comment box - * - * @return none - */ -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 = addCSVValue(textBox.value,stuff); - } -} - -/** - * Remove a keyword from the element if it is there - * - * @param id String with the id of the element - * @param stuff String/Array with keyword(s) to be removed - */ -function removeStuffFromTextBox (id, stuff) { - var changedElement = document.getElementById(id); - changedElement.value = removeCSVValue(changedElement.value,stuff); -} - -/** - * generalized hasKeyword ... search in the value of the box with given id - * - * @param id String with ID of the element we want to check - * @param str String to be searched for - * @return Boolean found? - */ -function idContainsWord (id, str) { - var kwd = ""; - try { - 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 (isInList(str, kwd.trim().split(/[,\s]+/))); -} - -/** - * Check for the presence of a keyword - * - * @param str String with the keyword - * @return Boolean - */ -function hasKeyword (str) { - return (idContainsWord('keywords', str)); -} - /** * dd * @@ -616,39 +371,6 @@ function getOptionTableCell(tableId, label) { } /** - * Set the bug to NEEDINFO state - * - * Working function. - * @return none - * @todo TODO we may extend this to general setNeedinfo function - * with parameter [reporter|assignee|general-email-address] - */ -function setNeedinfoReporter () { - clickMouse("needinfo"); - selectOption("needinfo_role", "reporter"); -} - -/** - * - */ -function getOwner () { - // TODO(maemo) doesn't work on maemo - var assigneeAElement = getOptionTableCell("bz_show_bug_column_1","Assigned To"); - return parseMailto(assigneeAElement); -} - -/** - * Return maintainer which is per default by bugzilla - * (which is not necessarily the one who is default maintainer per component) - * - * @return String with the maintainer's email address - */ -function getDefaultBugzillaMaintainer (component) { - var address = filterByRegexp(constantData.defBugzillaMaintainerArr, component); - return address; -} - -/** * Parse the row with the attachment * * @param DOM element to be parsed @@ -686,73 +408,6 @@ function parseAttachmentLine(inElem) { return [ attName, id, MIMEtype, size, inElem ]; } -/** - * collect the list of attachments in a structured format - * - * @return Array of arrays, one for each attachments; - * each record has string name of the attachment, integer its id number, - * string of MIME type, integer of size in kilobytes, and the whole - * element itself - */ -function getAttachments () { - var outAtts = []; - var atts = document.getElementById("attachment_table"). - getElementsByTagName("tr"); - for ( var i = 1, ii = atts.length - 1; i < ii; i++) { - outAtts.push(parseAttachmentLine(atts[i])); - } - return outAtts; -} - -/** - * Get login of the currently logged-in user. - * - * @return String with the login name of the currently logged-in user - */ -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; -} - -/** - * adds a person to the CC list, if it isn't already there - * - * @param who String with email address or "self" if the current user - * of the bugzilla should be added - */ -function addToCCList (who) { - if (!who) { - return ; - } - if (who === "self") { - document.getElementById("addselfcc").checked = true; - } - else { - clickMouse("cc_edit_area_showhide"); - if (!isInList(who, getCCList())) { - addStuffToTextBox("newcc",who); - } - } -} - -/** - * a collect a list of emails on CC list - * - * @return Array with email addresses as Strings. - */ -function getCCList () { - var CCListSelect = document.getElementById("cc"); - var outCCList = []; - if (CCListSelect) { - outCCList = Array.map(CCListSelect.options, function(item) { - return item.value; - }); - } - return outCCList; -} - function startup() { // First, preflight check ... if we are not logged in, there // is nothing we can do. diff --git a/data/lib/fixingAttMIME.js b/data/lib/fixingAttMIME.js new file mode 100644 index 0000000..9297c06 --- /dev/null +++ b/data/lib/fixingAttMIME.js @@ -0,0 +1,87 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php + +var reqCounter = 0; // TODO should be probably a dict indexed by called method + +/** + * Callback function for the XMLRPC request + * + * @param ret Object with xmlhttprequest response with attributes: + * + status -- int return code + * + statusText + * + responseHeaders + * + responseText + */ +function XMLRPCcallback() { + reqCounter--; + if (reqCounter <= 0) { + setTimeout(function () { + window.location.reload(true); + }, 1000); + } +} + +/** + * The worker function -- call XMLRPC to fix MIME type of the particular + * attachment + * + * @param id Integer with the attachment id to be fixed + * @param type String with the new MIME type, optional defaults to "text/plain" + * @param email Boolean whether email should be sent to appropriate person; + * option, defaults to false + * + * updateAttachMimeType($data_ref, $username, $password) + * + * Update the attachment mime type of an attachment. The first argument is a + * data hash containing information on the new MIME type and the attachment id + * that you want to act on. + * + * $data_ref = { "attach_id" => "<Attachment ID>", # Attachment ID to perform + * MIME type change on. "mime_type" => "<New MIME Type Value>", # Legal MIME + * type value that you want to change the attachment to. "nomail" => 0, # + * OPTIONAL Flag that is either 1 or 0 if you want email to be sent or not for + * this change }; + * + */ +function fixAttachById(id, type, email, XMLRPCURL) { + var params = []; + + if (type === undefined) { + type = "text/plain"; + } + if (email === undefined) { + email = false; + } + + // https://bugzilla.redhat.com/\ + // docs/en/html/api/extensions/compat_xmlrpc/code/webservice.html + // test on https://bugzilla.redhat.com/show_bug.cgi?id=485145 + params.push({ + 'attach_id' : id, + 'mime_type' : type, + 'nomail' : !email + }); + + postMessage(new Message("MakeXMLRPCall", { + url: XMLRPCURL, + login: getLogin(), + method: "bugzilla.updateAttachMimeType", + params: params, + callRPC: "FixAttachmentMIMECallback" + })); + reqCounter++; +} + +/** + * Add a link to the bad attachment for fixing it. + * + * @param + * <TR> DOM jQuery element with a bad attachment + * @return none + */ +function addTextLink(row, xmlRpcUrl) { + var elemS = row[4].getElementsByTagName("td"); + var elem = elemS[elemS.length - 1]; + createDeadLink("addFix2TextLink", "text", elem, + fixAttachById, [row[1], xmlRpcUrl], "br"); +} diff --git a/data/lib/makeBacktraceAttachment.js b/data/lib/makeBacktraceAttachment.js new file mode 100644 index 0000000..e938b11 --- /dev/null +++ b/data/lib/makeBacktraceAttachment.js @@ -0,0 +1,157 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php +var titleParsedAttachment = "Part of the thread where crash happened"; + +/** + * + */ +function pasteBacktraceInComments(atts) { + /* + Let's comment it out, and we'll see if anything breaks. + TODO This paragraph looks suspicous ... what is it? + Does it belong to this function? + var notedLabel = document.querySelector("label[for='newcc']"); + while (notedLabel.firstChild) { + var node = notedLabel.removeChild(notedLabel.firstChild); + notedLabel.parentNode.insertBefore(node, notedLabel); + } + notedLabel.parentNode.removeChild(notedLabel); + */ + + // FIXME BROKEN and its depending functions are even more broken + return null; + + var abrtQueryURL = "https://bugzilla.redhat.com/buglist.cgi?" + + "cmdtype=dorem&remaction=run&namedcmd=all%20NEW%20abrt%20crashes&"+ + "sharer_id=74116"; + + var mainTitle = document + .getElementsByClassName("bz_alias_short_desc_container")[0]; + + createDeadLink ("callAbrtQuery_link", + "Abrt bugs", mainTitle, abrtQueryURL, [], false, null, "a"); + + if (idContainsWord("cf_devel_whiteboard", 'btparsed')) { + addStuffToTextBox('status_whiteboard', 'btparsed'); + } + + if (!(isTriaged() || idContainsWord("status_whiteboard", + 'btparsed') || (atts.length > 0))) { + var btAttachments = atts + .filter(function(att) { + return (/File: backtrace/.test(att[0])); + }); + // TODO we need to go through all backtrace attachments, but + // just the first one will do for now, we would need to do async + // + btAttachments.forEach(function(x) { + var attURL = "https://bugzilla.redhat.com/attachment.cgi?id=" + + x[1]; + if ((!btSnippet) && // ???? FIXME + (!idContainsWord("status_whiteboard", 'btparsed'))) { + Request({ + url: attURL, + onComplete: function(response) { + if (response.status == 200) { + btSnippet = parseBacktrace(response.text); + if (btSnippet) { + addCheckShowLink(x,btSnippet); + } + } + } + }).get(); + } + }, this); + } + // Add "show BT" links + if (parsedAttachments.length > 0) { + this.parsedAttachments.forEach(function (att) { + addShowParsedBTLink(att); + }); + } +} + +/** + * Open new window with the content of the attachment. + * + * @param id Number of the attachment id + * @return none + */ +function showAttachment(id) { + postMessage(new Message("OpenURLinPanel", + "https://" + window.location.hostname + "/attachment.cgi?id=" + id)); +} + +/** + * add a link opening a window with the parsed backtrace + * + * @param att Attachment object + */ +function addShowParsedBTLink(att) { + var elem = att[4].querySelector("td:last-of-type"); + createDeadLink("showParsedBacktraceWindow-" + att[1], "showBT", + elem, showAttachment, att[1], true); +} + +/** + * Unfinished ... see above FIXME BROKEN AND DOESN'T WORK + */ +function addNewAttachmentRow(origAtt, + newAttId, newAttSize) { + var that = this; + var oldAddBTLink = document.getElementById("attachBacktraceActivator"); + oldAddBTLink.parentNode.removeChild(oldAddBTLink); + var newTRElem = origAtt[4].cloneNode(true); + + // fix number of the attachment + Array.forEach(newTRElem.getElementsByTagName("a"), function (aEl) { + aEl.setAttribute("href", + aEl.getAttribute("href").replace(origAtt[1], newAttId)); + }); + + var aElements = newTRElem.getElementsByTagName("a"); + aElements[0].setAttribute("name","parsed-backtrace.txt"); + aElements[0].getElementsByTagName("b")[0].textContent = titleParsedAttachment; + + var sizeSpan = newTRElem.getElementsByClassName("bz_attach_extra_info")[0]; + sizeSpan.textContent = "(" + (newAttSize / 1024).toFixed(2) + " KB, text/plain)"; + + // aElements[1].textContent = new Date().toString(); TODO we should add eventually, but not pressing + + var vcardSpan = newTRElem.getElementsByClassName("vcard")[0]; + if (vcardSpan !== undefined) { + var vcardSpanClassList = vcardSpan.classList; + if (/@redhat\.com/.test(this.login) && !vcardSpanClassList.contains("redhat_user")) { + vcardSpanClassList.add("redhat_user"); + } + var vcardAElem = vcardSpan.getElementsByTagName("a")[0]; + vcardAElem.setAttribute("title", this.login); + vcardAElem.setAttribute("href", "mailto:" + this.login); + vcardAElem.className = "email"; + vcardAElem.innerHTML="<span class='fn'>" + this.login + "</span>"; + } + + var elem = newTRElem.querySelector("td:last-of-type"); + this.createDeadLink("showBacktrace", "show BT", elem, + this.showAttachment, newAttId, false); + + origAtt[4].parentNode.insertBefore(newTRElem, origAtt[4].nextSibling); +} + +/** + * Add a link to create a new attachment with a parsed backtrace + * + * @param oldAtt Object with an attachment row + * @param snippet String with parsed backtrace + * @return none + */ +function addCheckShowLink(oldAtt, snippet) { + var elem = oldAtt[4].querySelector("td:last-of-type"); +/* + createDeadLink("attachBacktraceActivator", "add parsed BT", elem, function(x) { + // pass function and parameters as two separate parameters, the function to be called from + // addAttachment + addAttachment(snippet, addNewAttachmentRow, oldAtt); + }, [], true); +*/ +} diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js index 16adcea..b7bb7d5 100644 --- a/data/lib/otherButtons.js +++ b/data/lib/otherButtons.js @@ -92,6 +92,14 @@ function addingEmbelishments(list) { } } +/** + * 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 none + */ function setBranding(xLogAtts) { var brandColor = {}; var TriagedColor = {}; diff --git a/data/lib/queries.js b/data/lib/queries.js index b6e3661..0c00792 100644 --- a/data/lib/queries.js +++ b/data/lib/queries.js @@ -11,7 +11,6 @@ function getSelection () { return text; } - /** * Opens a new tab with a query for the given text in the selected component * @@ -73,3 +72,36 @@ function queryForSelection() { } } } + +/** + * + */ +function queryUpstreamCallback(text, queryUpBug) { + var searchData = filterByRegexp(queryUpBug, getComponent()); + var urlBase = searchData.url; + text = searchData.searchBy+":"+searchData.fillIn+" "+text.trim(); + if (searchData.fillIn == "$$$") { + text = text.replace("$$$", getComponent()); + } + text = encodeURIComponent(text).replace("%20","+"); + postMessage(new Message("OpenURLinTab", urlBase + text)); +} + +/** + * Search simple query in the upstream bugzilla appropriate for the component + * + * @return none + */ +function queryUpstream(qUpBug) { + if (!qUpBug) { + alert("We don't have constantData.queryUpstreamBug set up!"); + return null; + } + var text = getSelection(); + if (!text) { + postMessage(new Message("GetClipboard", "queryUpstream")); + } + else { + queryUpstreamCallback(text, qUpBug); + } +} diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index ddec25e..81116ba 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -1,8 +1,5 @@ // Released under the MIT/X11 license // http://www.opensource.org/licenses/mit-license.php -"use strict"; -var titleParsedAttachment = "Part of the thread where crash happened"; - // For identification of graphics card var manuChipStrs = [ [ "ATI Radeon", "ATI", "1002" ], @@ -57,7 +54,6 @@ var ProfessionalProducts = [ // END OF CONSTANTS var btSnippet = null; -var reqCounter = 0; // TODO should be probably a dict indexed by called method function RHOnMessageHandler(msg) { switch (msg.cmd) { @@ -77,7 +73,7 @@ function RHOnMessageHandler(msg) { findInterestingLine(msg.data, msg.cmd); break; case "queryUpstream": - queryUpstreamCallback(msg.data); + queryUpstreamCallback(msg.data, constantData.queryUpstreamBug); break; default: console.error("Error: unknown RPC call " + msg.toSource()); @@ -126,7 +122,7 @@ function RHcentralCommandDispatch(cmdLabel, cmdParams) { closeSomeRelease(); break; case "queryStringUpstreamBugzilla": - queryUpstream(); + queryUpstream(constantData.queryUpstreamBug); break; case "sendBugUpstream": sendBugUpstream(); @@ -144,198 +140,7 @@ function RHcentralCommandDispatch(cmdLabel, cmdParams) { } } -function addAttachmentCallback(resp) { - var newAttachID = parseInt(resp.params.param.value.array.data.value.int, 10); - console.log("attachID = " + newAttachID); - // FIXME callback.call(param, newAttachID, data.length); -} - -/** - * - * This has to stay in RHBugzillaPage because upstream doesn't have addAttachment - * XML-RPC call yet. - */ -function addAttachment(data, callback, param) { - var params = []; - - if (!constantData.passwordState.passAvailable) { - console.error("addAttachment : No password, no XML-RPC calls; sorry"); - return null; - } - - params.push(getBugNo()); - params.push({ - description: titleParsedAttachment, - filename: "parsed-backtrace.txt", - contenttype: "text/plain", - data: window.btoa(data), - nomail: true - }); - - postMessage(new Message("MakeXMLRPCall", { - url: constantData.XMLRPCData[window.location.hostname].url, - login: getLogin(), - method: "bugzilla.addAttachment", - params: params, - callRPC: "AddAttachmentCallback" - })); - reqCounter++; -} - /* === Bugzilla functions === */ -/** - * - */ -function pasteBacktraceInComments(atts) { - /* - Let's comment it out, and we'll see if anything breaks. - TODO This paragraph looks suspicous ... what is it? - Does it belong to this function? - var notedLabel = document.querySelector("label[for='newcc']"); - while (notedLabel.firstChild) { - var node = notedLabel.removeChild(notedLabel.firstChild); - notedLabel.parentNode.insertBefore(node, notedLabel); - } - notedLabel.parentNode.removeChild(notedLabel); - */ - - // FIXME BROKEN and its depending functions are even more broken - return null; - - var abrtQueryURL = "https://bugzilla.redhat.com/buglist.cgi?" + - "cmdtype=dorem&remaction=run&namedcmd=all%20NEW%20abrt%20crashes&"+ - "sharer_id=74116"; - - var mainTitle = document - .getElementsByClassName("bz_alias_short_desc_container")[0]; - - createDeadLink ("callAbrtQuery_link", - "Abrt bugs", mainTitle, abrtQueryURL, [], false, null, "a"); - - if (idContainsWord("cf_devel_whiteboard", 'btparsed')) { - addStuffToTextBox('status_whiteboard', 'btparsed'); - } - - if (!(isTriaged() || idContainsWord("status_whiteboard", - 'btparsed') || (atts.length > 0))) { - var btAttachments = atts - .filter(function(att) { - return (/File: backtrace/.test(att[0])); - }); - // TODO we need to go through all backtrace attachments, but - // just the first one will do for now, we would need to do async - // - btAttachments.forEach(function(x) { - var attURL = "https://bugzilla.redhat.com/attachment.cgi?id=" - + x[1]; - if ((!btSnippet) && // ???? FIXME - (!idContainsWord("status_whiteboard", 'btparsed'))) { - Request({ - url: attURL, - onComplete: function(response) { - if (response.status == 200) { - btSnippet = parseBacktrace(response.text); - if (btSnippet) { - addCheckShowLink(x,btSnippet); - } - } - } - }).get(); - } - }, this); - } - // Add "show BT" links - if (parsedAttachments.length > 0) { - this.parsedAttachments.forEach(function (att) { - addShowParsedBTLink(att); - }); - } -} - -/** - * Open new window with the content of the attachment. - * - * @param id Number of the attachment id - * @return none - */ -function showAttachment(id) { - postMessage(new Message("OpenURLinPanel", - "https://" + window.location.hostname + "/attachment.cgi?id=" + id)); -} - -/** - * add a link opening a window with the parsed backtrace - * - * @param att Attachment object - */ -function addShowParsedBTLink(att) { - var elem = att[4].querySelector("td:last-of-type"); - createDeadLink("showParsedBacktraceWindow-" + att[1], "showBT", - elem, showAttachment, att[1], true); -} - -/** - * Unfinished ... see above FIXME BROKEN AND DOESN'T WORK - */ -function addNewAttachmentRow(origAtt, - newAttId, newAttSize) { - var that = this; - var oldAddBTLink = document.getElementById("attachBacktraceActivator"); - oldAddBTLink.parentNode.removeChild(oldAddBTLink); - var newTRElem = origAtt[4].cloneNode(true); - - // fix number of the attachment - Array.forEach(newTRElem.getElementsByTagName("a"), function (aEl) { - aEl.setAttribute("href", - aEl.getAttribute("href").replace(origAtt[1], newAttId)); - }); - - var aElements = newTRElem.getElementsByTagName("a"); - aElements[0].setAttribute("name","parsed-backtrace.txt"); - aElements[0].getElementsByTagName("b")[0].textContent = titleParsedAttachment; - - var sizeSpan = newTRElem.getElementsByClassName("bz_attach_extra_info")[0]; - sizeSpan.textContent = "(" + (newAttSize / 1024).toFixed(2) + " KB, text/plain)"; - - // aElements[1].textContent = new Date().toString(); TODO we should add eventually, but not pressing - - var vcardSpan = newTRElem.getElementsByClassName("vcard")[0]; - if (vcardSpan !== undefined) { - var vcardSpanClassList = vcardSpan.classList; - if (/@redhat\.com/.test(this.login) && !vcardSpanClassList.contains("redhat_user")) { - vcardSpanClassList.add("redhat_user"); - } - var vcardAElem = vcardSpan.getElementsByTagName("a")[0]; - vcardAElem.setAttribute("title", this.login); - vcardAElem.setAttribute("href", "mailto:" + this.login); - vcardAElem.className = "email"; - vcardAElem.innerHTML="<span class='fn'>" + this.login + "</span>"; - } - - var elem = newTRElem.querySelector("td:last-of-type"); - this.createDeadLink("showBacktrace", "show BT", elem, - this.showAttachment, newAttId, false); - - origAtt[4].parentNode.insertBefore(newTRElem, origAtt[4].nextSibling); -} - -/** - * Add a link to create a new attachment with a parsed backtrace - * - * @param oldAtt Object with an attachment row - * @param snippet String with parsed backtrace - * @return none - */ -function addCheckShowLink(oldAtt, snippet) { - var elem = oldAtt[4].querySelector("td:last-of-type"); -/* - createDeadLink("attachBacktraceActivator", "add parsed BT", elem, function(x) { - // pass function and parameters as two separate parameters, the function to be called from - // addAttachment - addAttachment(snippet, addNewAttachmentRow, oldAtt); - }, [], true); -*/ -} /** * Make it sailent that the some attachments with bad MIME type are present @@ -361,79 +166,16 @@ function markBadAttachments(atts) { createDeadLink("fixAllButton", "Fix all", titleElement, function() { Array.forEach(badAttachments, function(x) { - fixAttachById(x[1]); + fixAttachById(x[1], constantData.XMLRPCData[window.location.hostname].url); }); }, [], false, null, "f"); badAttachments.forEach(function(x, i, a) { - addTextLink(x); + addTextLink(x, constantData.XMLRPCData[window.location.hostname].url); }); } } /** - * Is this bug a RHEL bug? - * - * @return Boolean true if it is a RHEL bug - */ -function isEnterprise() { - var result = ProfessionalProducts.some(function(elem,idx,arr) { - return new RegExp(elem).test(getProduct()); - }); - return result; -} - -/** - * Find out whether the bug is needed an attention of bugZappers - * - * @return Boolean whether the bug has been triaged or not - */ -function isTriaged() { - return hasKeyword("Triaged"); -} - -/** - * 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 none - */ - -/** - * - */ -function queryUpstreamCallback(text) { - var searchData = filterByRegexp(constantData.queryUpstreamBug, getComponent()); - var urlBase = searchData.url; - text = searchData.searchBy+":"+searchData.fillIn+" "+text.trim(); - if (searchData.fillIn == "$$$") { - text = text.replace("$$$", getComponent()); - } - text = encodeURIComponent(text).replace("%20","+"); - postMessage(new Message("OpenURLinTab", urlBase + text)); -} - -/** - * Search simple query in the upstream bugzilla appropriate for the component - * - * @return none - */ -function queryUpstream() { - if (!constantData.queryUpstreamBug) { - alert("We don't have constantData.queryUpstreamBug set up!"); - return null; - } - var text = getSelection(); - if (!text) { - postMessage(new Message("GetClipboard", "queryUpstream")); - } - else { - queryUpstreamCallback(text); - } -} - -/** * Open a tab in the upstream bugzilla to create a new bug * * @return none @@ -594,107 +336,6 @@ function findInterestingLine(wholeLog, backMsg) { } /** - * 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 = ""; - var bzLabelNames = constantData.bugzillaLabelNames; - if (bzLabelNames[URLhostname]) { - bugzillaID = bzLabelNames[URLhostname]; - } - else { - bugzillaID = ""; - } - return bugzillaID; -} - -/** - * Callback function for the XMLRPC request - * - * @param ret Object with xmlhttprequest response with attributes: - * + status -- int return code - * + statusText - * + responseHeaders - * + responseText - */ -function XMLRPCcallback() { - reqCounter--; - if (reqCounter <= 0) { - setTimeout(function () { - window.location.reload(true); - }, 1000); - } -} - -/** - * The worker function -- call XMLRPC to fix MIME type of the particular - * attachment - * - * @param id Integer with the attachment id to be fixed - * @param type String with the new MIME type, optional defaults to "text/plain" - * @param email Boolean whether email should be sent to appropriate person; - * option, defaults to false - * - * updateAttachMimeType($data_ref, $username, $password) - * - * Update the attachment mime type of an attachment. The first argument is a - * data hash containing information on the new MIME type and the attachment id - * that you want to act on. - * - * $data_ref = { "attach_id" => "<Attachment ID>", # Attachment ID to perform - * MIME type change on. "mime_type" => "<New MIME Type Value>", # Legal MIME - * type value that you want to change the attachment to. "nomail" => 0, # - * OPTIONAL Flag that is either 1 or 0 if you want email to be sent or not for - * this change }; - * - */ -function fixAttachById(id, type, email) { - var params = []; - - if (type === undefined) { - type = "text/plain"; - } - if (email === undefined) { - email = false; - } - - // https://bugzilla.redhat.com/\ - // docs/en/html/api/extensions/compat_xmlrpc/code/webservice.html - // test on https://bugzilla.redhat.com/show_bug.cgi?id=485145 - params.push({ - 'attach_id' : id, - 'mime_type' : type, - 'nomail' : !email - }); - - postMessage(new Message("MakeXMLRPCall", { - url: constantData.XMLRPCData[window.location.hostname].url, - login: getLogin(), - method: "bugzilla.updateAttachMimeType", - params: params, - callRPC: "FixAttachmentMIMECallback" - })); - reqCounter++; -} - -/** - * Add a link to the bad attachment for fixing it. - * - * @param - * <TR> DOM jQuery element with a bad attachment - * @return none - */ -function addTextLink(row) { - var elemS = row[4].getElementsByTagName("td"); - var elem = elemS[elemS.length - 1]; - createDeadLink("addFix2TextLink", "text", elem, - fixAttachById, row[1], "br"); -} - -/** * Add information about the upstream bug upstream, and closing it. * * @param evt Event which called this handler @@ -719,7 +360,7 @@ function addClosingUpstream() { inputBox.value = externalBugID; } // get bugzillaName and set the label - var bugzillaName = getBugzillaName(wholeURL.host); + var bugzillaName = getBugzillaName(wholeURL.host, constantData.bugzillaLabelNames); selectOptionByLabel("external_id", bugzillaName); } else if (!isNaN(inputBox.value)) { diff --git a/data/lib/util.js b/data/lib/util.js index 6cbb493..611d353 100644 --- a/data/lib/util.js +++ b/data/lib/util.js @@ -81,6 +81,19 @@ function getBugNoFromURL(url) { } /** + * Send mouse click to the specified element + * + * @param String ID of the element to send mouseclick to + * @return None + */ +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); + document.getElementById(targetID).dispatchEvent(localEvent); +} + +/** * Create a A element leadink nowhere, but with listener running a callback on the click * * @param id String with a id to be added to the element diff --git a/lib/main.js b/lib/main.js index 6c91da1..80144cc 100644 --- a/lib/main.js +++ b/lib/main.js @@ -116,12 +116,15 @@ var contentScriptLibraries = [ self.data.url('lib/urltest.js'), self.data.url("lib/jumpNextBug.js"), self.data.url("lib/util.js"), - self.data.url("lib/queries.js"), + self.data.url("lib/queries.js"), self.data.url("lib/preprocessDuplicates.js"), self.data.url("lib/viewSource.js"), self.data.url("lib/color.js"), self.data.url("lib/addNewLinks.js"), + self.data.url("lib/bugzillaDOMFunctions.js"), self.data.url("lib/otherButtons.js"), + self.data.url("lib/makeBacktraceAttachment.js"), + self.data.url("lib/fixingAttMIME.js"), self.data.url("lib/logging-front.js"), self.data.url('lib/bug-page-mod.js'), self.data.url("lib/rhbzpage.js"), |