aboutsummaryrefslogtreecommitdiffstats
path: root/bugzillaBugTriage.js
diff options
context:
space:
mode:
Diffstat (limited to 'bugzillaBugTriage.js')
-rw-r--r--bugzillaBugTriage.js322
1 files changed, 233 insertions, 89 deletions
diff --git a/bugzillaBugTriage.js b/bugzillaBugTriage.js
index 87eb78a..517df99 100644
--- a/bugzillaBugTriage.js
+++ b/bugzillaBugTriage.js
@@ -24,7 +24,7 @@ var TriagedDistro = 13;
var NumberOfFrames = 7;
var XMLRPCurl = "https://bugzilla.redhat.com/xmlrpc.cgi";
var bugURL = "https://bugzilla.redhat.com/show_bug.cgi?id=";
-var myConfig = jetpack.storage.simple;
+var myStorage = jetpack.storage.simple;
var badMIMEArray = ["application/octet-stream","text/x-log","undefined"];
//==============================================================
@@ -41,7 +41,7 @@ jetpack.future.import("storage.settings");
// jetpack.settings.open();
//}
-var jsonDataURL = myConfig.JSONURL ? myConfig.JSONURL :
+var jsonDataURL = myStorage.JSONURL ? myStorage.JSONURL :
"http://mcepl.fedorapeople.org/scripts/BugZappers_data.json";
var PCIIDsURL = "http://mcepl.fedorapeople.org/scripts/drm_pciids.json";
var abrtQueryURL = "https://bugzilla.redhat.com/buglist.cgi?"+
@@ -85,6 +85,7 @@ var suspiciousComponents = [];
var signatureFedoraString = "";
// TODO we should have an array SpecialFlags instead of multiple Boolean variables
var queryButtonAvailable = false;
+var upstreamButtonAvailable = false;
var chipIDsGroupings = [];
var AddrArray = [];
var PCI_ID_Array = [];
@@ -146,6 +147,25 @@ loadJSON(PCIIDsURL,
PCI_ID_Array = response;
});
+//======== load external library ===============================
+
+var XMLRPCMessage = {};
+var req = new XMLHttpRequest();
+req.open("GET","http://mcepl.fedorapeople.org/scripts/xmlrpc.js",true);
+req.onreadystatechange = function (aEvt) {
+ if (req.readyState == 4) {
+ if (req.status == 200) {
+ var thisDoc = jetpack.tabs.focused.contentDocument;
+ var script = thisDoc.createElement("script");
+ script.setAttribute("type","text/javascript");
+ script.innerHTML = req.responseText;
+ thisDoc.getElementsByTagName("head")[0].appendChild(script);
+ XMLRPCMessage = jetpack.tabs.focused.contentWindow.wrappedJSObject.XMLRPCMessage;
+ }
+ }
+};
+req.send("");
+
//==============================================================
/**
@@ -459,6 +479,152 @@ BzPage.prototype.getOptionValue = function (id) {
return this.dok.getElementById(id).value;
};
+/* Offline supporting functions */
+/**
+ *
+ * @todo FIXME this probably makes a closure and a memory leak
+ * name='changeform'
+ * investigate https://developer.mozilla.org/en/How_to_Turn_Off_Form_Autocompletion
+ *
+ * <form method="post" action="process_bug.cgi" autocomplete="off">
+
+ Reading http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.13
+ random notes:
+ - 17.13.3 provides all steps necessary
+ - enctype != application/x-www-form-urlencoded => SHOULD fails (no further questions needed)
+ - http://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2.1. is nice explanation
+ (albeit quite dated)
+ - on multiple values http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.6.1
+ - příliš jednoduché http://www.innovation.ch/java/HTTPClient/emulating_forms.html
+ -
+ */
+BzPage.prototype.serializeForm = function (form) {
+ var serialForm = {
+ dataOut: "",
+ name: form.name,
+ method: form.method,
+ acceptCharset: form.acceptCharset,
+ action: form.action, // TODO shouldn't we get a non-relative URL?
+ enctype: form.enctype,
+ cookie: this.dok.cookie,
+ autocomplete: form.getAttribute("autocomplete"),
+ bugNo: this.bugNo
+ };
+
+ function genURIElement(sName,sValue) {
+ return encodeURIComponent(sName)+"="+
+ encodeURIComponent(sValue);
+ }
+
+ /**
+ * @param o control to be serialized
+ * @return String with the serialized control
+ */
+ function serializeControl(element) {
+ var val = element.value;
+ console.log("val.toSource() = " + val.toSource());
+ /*
+ on HTMLSelectElement we have an attribute 'type' of type DOMString, readonly
+ The type of this form control. This is the string "select-multiple"
+ when the multiple attribute is true and the string "select-one" when
+ false.
+ */
+ if ((val == null) || (val == undefined)|| (val == "")) {
+ return ;
+ } else if (val instanceof Array) {
+ return val.map(function (x) {
+ return genURIElement(element.name,x.value);
+ }).join("&");
+ } else if (val instanceof String) {
+ return genURIElement(element.name,val);
+ } else { // assume HTMLCollection
+ return Array.map(val,function (x) {
+ return genURIElement(element.name,x.value);
+ }).join("&");
+ }
+ }
+
+ serialForm.dataOut = Array.filter(form.elements,function (el) {
+ return !el.disabled && el.name &&
+ // FIXME shouldn't I just add && el.value here?
+ (el.checked || /select|textarea/i.test(el.nodeName) ||
+ /text|hidden|password|search/i.test(el.type));
+ }).map(serializeControl).join("&");
+ return serialForm;
+};
+
+BzPage.prototype.submitCallback = function(evt) {
+ console.log("Submit Callback!");
+ if (jetpack.__parent__.navigator.onLine) {
+ var serForm = this.serializeForm(jetpack.tabs.focused.
+ contentWindow.document.forms.namedItem("changeform"));
+ console.log("serForm:\n"+serForm.toSource());
+ } else {
+ var serForm = this.serializeForm(jetpack.tabs.focused.
+ contentWindow.document.forms.namedItem("changeform"));
+ myStorage.forms[this.bugNo] = serForm;
+ evt.stopPropagation();
+ evt.preventDefault();
+ }
+};
+
+/**
+ *
+ *
+ * Yes, this is correct, this is NOT method of bzPage!
+ */
+function onlineCallback() {
+ function deserializeAndSend(formData) {
+ // FIXME notImplemented
+ // is it enough to just
+ // run XMLHttpRequest? Probably yes, this is just a form
+ // and this is just a HTTP request
+ // it is probably better to get already processed
+ // application/x-www-form-urlencoded
+ // see http://htmlhelp.com/reference/html40/forms/form.html for details
+ // and also https://developer.mozilla.org/en/AJAX/Getting_Started
+ // what's?
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference\
+ // /Global_Functions/encodeURI & co.
+ // this seems to be also interesting
+ // https://developer.mozilla.org/en/Code_snippets/Post_data_to_window
+ console.error("Sending bugs not implemented yet!");
+ return ""; // FIXME check other HTTP headers to be set
+
+ var bugID = formData.bugNo;
+ var req = new XMLHttpRequest();
+ req.open("POST",formData.action,true);
+ // FIXME co očekávám za odpověď? req.overrideMimeType("text/xml");
+ // * Accept-Encoding
+ // * Accept-Language
+ // * Accept (MIME types)
+ req.setRequestHeader("Connection","keep-alive");
+ req.setRequestHeader("Keep-Alive",300);
+ req.setRequestHeader("Content-Type",formData.enctype);
+ req.setRequestHeader("Referer",bugURL+bugID);
+ req.setRequestHeader("Accept-Charset",formData.acceptCharset);
+ req.setRequestHeader("Cookie",formData.cookie)
+ req.onreadystatechange = function (aEvt) {
+ if (req.readyState == 4) {
+ if (req.status == 200) {
+ console.log("Sent form for bug " + bugID);
+ delete myStorage.forms[bugID];
+ } else {
+ console.error("Sending form for bug " + bugID +
+ "failed!");
+ }
+ }
+ };
+ req.send(formData.data);
+ }
+
+ if (myStorage.forms.length > 0) {
+ myStorage.forms.forEach(function (x) {
+ deserializeAndSend(x);
+ });
+ }
+}
+
/* Bugzilla functions.*/
/**
@@ -776,7 +942,7 @@ BzPage.prototype.addNewButton = function (originalLocation,newId,newLabel,
newButton.value = newLabel;
newButton.addEventListener("click",function (evt) {
that.generalPurposeCureForAllDisease(commStr,nState, secPar);
- },false);
+ }, false);
if (after) {
originalLocation.parentNode.insertBefore(newButton,
@@ -834,7 +1000,7 @@ BzPage.prototype.fillInChipMagic = function () {
interestingArray = ChipsetRE.exec(interestingLineArr[0]);
interestingLine = interestingArray[2].
replace(/[\s"]+/g," ").trim();
- var whiteboardInput = this.dok.
+ var whiteboardInput = that.dok.
getElementById("status_whiteboard");
that.addNewButton(whiteboardInput,"chipmagic","Fill In",
"","CHIPMAGIC",
@@ -912,13 +1078,24 @@ BzPage.prototype.sendBugUpstream = function() {
var url = filterByRegexp(upstreamBugzillasArray,
this.getOptionValue("component"));
- var text = this.dok.getElementById("short_desc_nonedit_display").
- textContent.trim() + "\n\n";
- text += this.collectComments();
- jetpack.clipboard.set(text);
var ret = jetpack.tabs.open(url);
- console.log("opening new tab returned");
- console.log(ret);
+ var that = this;
+ console.log("Setting up load listener");
+ jetpack.tabs.onReady(function() {
+ var otherDoc = ret.contentDocument;
+ console.log("otherDoc");
+ console.log(otherDoc);
+ var otherElems = otherDoc.forms.namedItem("Create").elements;
+ otherElems.namedItem("short_desc").value =
+ that.dok.getElementById("short_desc_nonedit_display").
+ textContent.trim();
+ otherElems.namedItem("comment").value = that.collectComments();
+ ret.focused();
+
+ console.log("opening new tab returned");
+ console.log(ret);
+
+ });
};
/**
@@ -943,9 +1120,6 @@ BzPage.prototype.parseAttachmentLine = function (inElem) {
// getting name of the attachment
var attName = inElem.getElementsByTagName("b")[0].textContent.trim();
- // getting id
- // $("a:contains('Details')", inElem);
- // FIXME isn't there more simple way to replace above? querySelector?
var aHrefsArr = inElem.getElementsByTagName("a");
var aHref = Array.filter(aHrefsArr,function (x) {
return x.textContent.trim() == "Details";
@@ -1091,21 +1265,18 @@ BzPage.prototype.getWholeURL = function(selectValue,bugID) {
*/
BzPage.prototype.callBack = function(data,textStatus) {
if (--this.reqCounter <= 0) {
- setTimeout(document.location.reload,1000);
+ setTimeout(this.dok.location.reload,1000);
}
};
/**
- * Create XML-RPC message for updateAttachMimeType procedure with given parameters.
- * Yes, I know this is very ugly, but in the current state of jetpack it is not possible
- * to import external jQuery modules, so I cannot use jquery.rpc as much as I would like to.
+ * The worker function -- call XMLRPC to fix MIME type of the
+ * particular attachment
*
- * @param login string with login
- * @param password string with password
- * @param attachID Number with the attachment ID#
- * @param mimeType stri ng with MIME type, optional and defaults to text/plain
- * @param email Boolean whether we should send email or not
- * @return string with the XML-RPC message
+ * @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)
@@ -1119,56 +1290,24 @@ Update the attachment mime type of an attachment. The first argument is a data h
"nomail" => 0,
# OPTIONAL Flag that is either 1 or 0 if you want email to be sent or not for this change
};
+
*/
-BzPage.prototype.createXMLRPCMessage = function(login,password,attachId,mimeType,email) {
- if (mimeType === undefined) {
- mimeType = "text/plain";
+BzPage.prototype.fixAttachById = function(id,type,email) {
+ if (type === undefined) {
+ type = "text/plain";
}
if (email === undefined) {
email = false;
}
- var emailStr = email ? "0" : "1";
-
- var msg = <methodCall>
- <methodName>bugzilla.updateAttachMimeType</methodName>
- <params>
- <param>
- <value><struct>
- <member>
- <name>attach_id</name>
- <value><i4>{attachId}</i4></value>
- </member>
- <member>
- <name>mime_type</name>
- <value><string>{mimeType}</string></value>
- </member>
- <member>
- <name>nomail</name>
- <value><boolean>{emailStr}</boolean></value>
- </member>
- </struct></value>
- </param>
- <param>
- <value><string>{login}</string></value>
- </param>
- <param>
- <value><string>{password}</string></value>
- </param>
- </params>
- </methodCall>;
- return msg.toXMLString();
-};
-/**
- * The worker function -- call XMLRPC to fix MIME type of the
- * particular attachment
- *
- * @param id integer with the attachment id to be fixed
- * @param type string with the new MIME type, e.g. "text/plain"
- */
-BzPage.prototype.fixAttachById = function(id,type) {
- var msg = this.createXMLRPCMessage(this.login,this.password,id,type);
+ var msg = new XMLRPCMessage("bugzilla.updateAttachMimeType");
+ msg.addParameter({'attach_id':id, 'mime_type':type, 'nomail':!email});
+ msg.addParameter(this.login);
+ msg.addParameter(this.password);
+ console.log("testing XMLRPCMessage:\n" + msg.xml());
+
var req = new XMLHttpRequest();
+ var that = this;
req.open("POST",XMLRPCurl,true);
req.overrideMimeType("text/xml");
req.setRequestHeader("Content-type","text/xml");
@@ -1182,17 +1321,16 @@ BzPage.prototype.fixAttachById = function(id,type) {
}
}
};
- req.send(msg);
+ req.send(msg.xml());
this.reqCounter++;
};
+// FIXME possibly eliminate this function altogether and
+// make it inline?
BzPage.prototype.fixAllAttachments = function(list) {
- var tmpElem = {};
-
- for(var i=0;i<list.length;i++) {
- tmpElem = list[i];
- this.fixAttachById(tmpElem[1]);
- }
+ Array.forEach(list,function (x) {
+ this.fixAttachById(x[1]);
+ }, this);
};
/**
@@ -1209,7 +1347,7 @@ BzPage.prototype.createFixAllButton = function (list) {
elem.innerHTML = "<b>F</b>ix all";
elem.addEventListener("click", function() {
that.fixAllAttachments(list);
- },false);
+ }, false);
return elem;
};
@@ -1469,12 +1607,12 @@ BzPage.prototype.buildButtons = function (above,below) {
if (queryButtonAvailable) {
// Add query search button
this.addNewButton(brElementPlacer,"newqueryintab",
- "Query for string","","QUERYSEL","",false);
+ "Query for string","","QUERYSEL","", false);
}
// Button for upstreaming
if (upstreamButtonAvailable) {
this.addNewButton(brElementPlacer,"sendupstream",
- "Send upstream","","SENDUPSTREAM","",false);
+ "Send upstream","","SENDUPSTREAM","", false);
}
// var brElement2BMoved = this.dok.querySelector("#comment_status_commit br:last-of-type");
@@ -1508,18 +1646,16 @@ function BzPage(doc) {
var that = this;
this.originalButton = this.dok.getElementById("commit");
- console.log(this.dok.querySelector("#header ul.links li:last-of-type"));
var loginArr = this.dok.
querySelector("#header ul.links li:last-of-type").
textContent.split("\n");
this.login = loginArr[loginArr.length-1].trim();
- this.password = "";
// the following is quite awful brutal hack
console.log("on __parent__ navigator.online = " +
jetpack.__parent__.navigator.onLine);
- if (myConfig.BZpassword) {
- this.password = myConfig.BZpassword;
+ if (myStorage.BZpassword) {
+ this.password = myStorage.BZpassword;
} else {
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
@@ -1531,7 +1667,7 @@ function BzPage(doc) {
// set if OK was pressed. The checkbox is not displayed.
if (result) {
this.password = password.value;
- myConfig.BZpassword = this.password;
+ myStorage.BZpassword = this.password;
jetpack.storage.simple.sync();
}
}
@@ -1583,7 +1719,8 @@ function BzPage(doc) {
// Dig out backtrace
this.btSnippet = "";
- var bugTitle = this.dok.getElementById("short_desc_nonedit_display").textContent;
+ var bugTitle = this.dok.getElementById("short_desc_nonedit_display").
+ textContent;
if (AbrtRE.test(bugTitle)) {
var notedLabel = this.dok.querySelector("label[for='newcc']");
@@ -1601,7 +1738,8 @@ function BzPage(doc) {
abrtButton.textContent = "Abrt bugs";
mainTitle.appendChild(abrtButton);
var develWhiteboardElem = this.dok.getElementById("cf_devel_whiteboard");
- var develWhiteboard = develWhiteboardElem ? develWhiteboardElem.value : "btparsed";
+ var develWhiteboard = develWhiteboardElem ? develWhiteboardElem.
+ value : "btparsed";
if (!(this.hasKeyword("Triaged") || (/btparsed/.test(develWhiteboard)))) {
var btAttachments = this.attachments.filter(function (att,idx,arr) {
@@ -1632,7 +1770,7 @@ function BzPage(doc) {
function () {
that.addTextToTextBox("comment", signatureFedoraString);
}
- ,false);
+ , false);
}
this.setBranding();
@@ -1643,7 +1781,7 @@ function BzPage(doc) {
var additionalButtons = this.dok.getElementById("bugzilla-body").
getElementsByClassName("related_actions")[0];
var customJSONURLUI = this.dok.createElement("li");
- customJSONURLUI.innerHTML = " - <a href='#' id='customJSONbutton'>" +
+ customJSONURLUI.innerHTML = "\u00A0-\u00A0<a href='#' id='customJSONbutton'>" +
"BugZap config</a>";
additionalButtons.appendChild(customJSONURLUI);
this.dok.getElementById("customJSONbutton").
@@ -1651,11 +1789,11 @@ function BzPage(doc) {
var newURL = jetpack.tabs.focused.contentWindow.
prompt("URL for your JSON customization file");
if (newURL) {
- myConfig.JSONURL = newURL;
+ myStorage.JSONURL = newURL;
jetpack.storage.simple.sync();
jetpack.tabs.focused.contentWindow.location.reload();
}
- },false);
+ }, false);
// set default assignee on change of the component
this.dok.getElementById("component").addEventListener("change",
@@ -1663,7 +1801,13 @@ function BzPage(doc) {
that.component = that.getOptionValue("component");
that.changeOwner(filterByRegexp(defAssigneeList, that.component).
toLowerCase());
- },false);
+ }, false);
+
+ // offline-capable submit
+ this.dok.forms.namedItem("changeform").
+ addEventListener('submit', function (evt) {
+ that.submitCallback.call(that, evt)},
+ false);
}
var callback = function (doc) {
@@ -1673,5 +1817,5 @@ var callback = function (doc) {
var options = {};
options.matches = [
"https://bugzilla.redhat.com/show_bug.cgi"
- ];
+];
jetpack.pageMods.add(callback, options);