// Released under the MIT/X11 license // http://www.opensource.org/licenses/mit-license.php jetpack.future.import("pageMods"); jetpack.future.import("storage.simple"); // ************* FUNCTIONS ******************** /* EXTERNAL FUNCTIONS */ /** * This function creates a new anchor element and uses location properties (inherent) * to get the desired URL data. Some String operations are used (to normalize results * across browsers). * originally from http://snipplr.com/view.php?codeview&id=12659 * * @param url String with URL * @return object with parameters set * */ function parseURL(url) { var a = jetpack.tabs.focused.contentDocument.createElement('a'); a.href = url; return { source: url, protocol: a.protocol.replace(':',''), host: a.hostname, port: a.port, query: a.search, params: (function(){ var ret = {}, seg = a.search.replace(/^\?/,'').split('&'), len = seg.length, i = 0, s; for (;i 0) { chosenPair = list.filter( function(pair){ return RegExp(pair['regexp'],"i").test(chosingMark); }); }; if (chosenPair.length > 0) { return trim(chosenPair[0]['addr']); } else { return ""; } } /** * Converts attributes value of the given list of elements to the * Javascript list. * * @param list array of elements * @return array of values */ function valuesToList(list) { var outL = []; var member = ""; for (var element in list) { if (element.hasAttribute("value")) { outL[outL.length] = trim(element.getAttribute("value")); } } return outL; } /** * Check whether an item is member of the list. Idea is just to * make long if commands slightly more readable. * * @param mbr string to be searched in the list * @param list list * @return position of the string in the list, or -1 if none found. */ function isInList(mbr,list) { return(list.indexOf(mbr) !== -1); } /** * returns content of the system clipboard * @return string with the content of the clipboard or "" if empty. * originally from * https://developer.mozilla.org/en/Using_the_Clipboard * */ // TODO to-be-replaced by // var contents = jetpack.clipboard.get(); function getClipboardText() { this.netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); var clip = Components.classes["@mozilla.org/widget/clipboard;1"].getService(Components.interfaces.nsIClipboard); if (!clip) return false; var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable); if (!trans) return false; trans.addDataFlavor("text/unicode"); clip.getData(trans, clip.kGlobalClipboard); var str = new Object(); var strLength = new Object(); trans.getTransferData("text/unicode", str, strLength); if (str) str = str.value.QueryInterface(Components.interfaces.nsISupportsString); if (str) pastetext = str.data.substring(0, strLength.value / 2); return pastetext; }; /* Bugzilla functions.*/ /** * add Fedora Bug zapper's signature to the comment of the current bug */ function addSignature(evt) { var cmntText = $("#comment",document); if ((signatureFedoraString.length > 0) && (trim(cmntText.value).length > 0)) { cmntText.value = trim(cmntText.value) + signatureFedoraString; } } /** * Send mouse click to the specified element * @param element where to send mouseclick to * @return None */ function clickMouse(target) { var localEvent = jetpack.tabs.focused.contentDocument.createEvent("MouseEvents"); localEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); target.dispatchEvent(localEvent); } /** * Parse the row with the attachment * @param element to be parsed * @return array with string name of the attachment, integer its id number, string of MIME type, integer of size in kilobytes, and the whole element itself */ function parseAttachmentLine(inElem) { var name = String(); var MIMEtype = String(); var size = Number(); var id = Number(); // FIXME we should skip obsolete attachments inElem.normalize(); // getting name of the attachment var bElem = inElem.getElementsByTagName("b")[0]; name = trim(bElem.textContent); // getting id var aElem = inElem.getElementsByTagName("a")[0]; id = parseInt(aElem.getAttribute("href").replace(/^.*attachment.cgi\?id=/,""),10); //getting MIME type and size var spanElems = inElem.getElementsByClassName("bz_attach_extra_info")[0]; var roundedText = spanElems.innerHTML; var stringArray = trim(roundedText.replace(/^\s*\((.*)\s*KB,\s*$/,"$1")); size = parseInt(stringArray,10); MIMEtype = roundedText.split("\n")[2].replace(/^\s*(.*)\)\s*$/,"$1"); return([name,id,MIMEtype,size,inElem]); } /** * Get list of attachments to the bug * * @return array of attachments */ function getAttachments(attTable) { var attList = Array(); var tempT = attTable.getElementsByTagName("tr"); if (tempT.length > 2) { for (var i=1;i0) { var titleElement = $(".bz_alias_short_desc_container:first",document); titleElement.css("background-color","olive"); titleElement.append(createFixAllButton(badAttachments)); for(var i=0;i 0) { cardIDStr = cardIDArr[0]; if (cardIDArr[1]) { optionStr = cardIDArr[1]; outStr = groupIDs(driverStr,cardIDStr)+"/" + optionStr; console.log("cardIDArr = " + cardIDArr.toSource() + ", outStr = "+outStr); } else { outStr = groupIDs(driverStr,cardIDStr); optionStr = ""; } console.log("found IDs: " + cardIDStr + "," + optionStr); } else { outStr = "**** FULLSTRING: " + iLine; } } else { // Intel Corporation, NVIDIA cardIDArr = manuChipStrs.filter(function (el, ind, arr) { return RegExp(el[0],"i").test(iLine); }); console.log("cardIDArr = " + cardIDArr.toSource()); if (cardIDArr && (cardIDArr.length > 0)) { cardIDArr = cardIDArr[0]; } else { outStr = iLine; break chipSwitchboard; } // cardIDArr [0] = RE, [1] = ("RADEON","INTEL","NOUVEAU"), [2] = manu PCIID iLine = trim(iLine.replace(RegExp(cardIDArr[0],"i"),"")); // FIXME is this necessary? Let's try without it // outStr = iLine.replace(/^\W*(\w*).*$/,"$1"); // nVidia developers opted-out from grouping if (driverStr == "INTEL") { outStr = groupIDs(cardIDArr[1],iLine); } else { outStr = iLine; } } console.log("result = " + outStr); var whiteboardInput = $("#status_whiteboard",document); var attachedText = trim("card_"+outStr); if (whiteboardInput.value.length == 0) { whiteboardInput.value = attachedText; } else { whiteboardInput.value += ", " + attachedText; } } /** * Insert "Fill In" button to the status whiteboard * @param interestLine string with the interesting part of the Chipset: line * @param driverString string with name of the driver ("INTEL", "RADEON", "NOUVEAU", * etc.) * @return none */ function fillInAddButton(interestLine,driverString) { var newButt = originalButton.cloneNode(true); var whiteboardInput = $("#status_whiteboard",document); newButt.setAttribute("id","chipmagic"); newButt.setAttribute("value","Fill In"); newButt.addEventListener('click',function (evt) { fillInWhiteBoard(interestLine,driverString); },true); newButt.setAttribute("type","button"); whiteboardInput.parentNode.appendChild(newButt); whiteboardInput.parentNode.insertBefore(jetpack.tabs.focused.contentDocument.createTextNode("\u00A0"),newButt); } /** * Recursive function to run Get attached Xorg.0.log, parse it and find the value of chip * @return None */ function fillInChipMagicProcessAtts(ret) { if (ret) { if (ret.status != 200) { alert([ret.status,ret.statusText,ret.responseHeaders, ret.responseText]); throw "XMLHttpRequest got return code " + ret.status; } console.log('fetched ' + ret.finalUrl); var interestingLineArr = ret.responseText.split("\n").filter(function (v,i,a) { return ChipsetRE.test(v); }); console.log("interestingLineArr = " + interestingLineArr.toSource()); if (interestingLineArr.length >0) { // Process and exit // .replace(ChipsetRE,"$1\t$2").split("\t") var interestingArray = ChipsetRE.exec(interestingLineArr[0]); console.log("interesting array = " + interestingArray.toSource()); interestingLine = trim(interestingArray[2].replace(/[\s"]+/g," ")); console.log("interesting line = " + interestingLine); fillInAddButton(interestingLine,interestingArray[1].toUpperCase()); console.log("XMLHttpRequest done!"); return; } } if (XorgLogAttList[XorgLogAttListIndex]) { var XorgLogAttID = XorgLogAttList[XorgLogAttListIndex][1]; var attURL = "https://bugzilla.redhat.com/attachment.cgi?id="+XorgLogAttID; XMLHttpRequest({ method: 'GET', url: attURL, headers: { 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey getXorgLog', 'Accept': 'text/plain', 'Content-type': 'text/xml' }, onload:fillInChipMagicProcessAtts }); XorgLogAttListIndex++; } else { console.log("No more Xorg.0.log attachments!"); } } /** * Get attached Xorg.0.log, parse it and find the value of chip. * Does not fill the whiteboard itself, just adds button to do so, so that * slow XMLHttpRequest is done in advance. * @param none * @return none */ function fillInChipMagic() { var XorgLogURL = ""; var XorgLogAttID = ""; var XorgLogFound = false; // Find out Xorg.0.log attachment URL XorgLogAttList = attachmentsList.filter(function (value, index, array) { // Xorg.0.log must be text, otherwise we cannot parse it return (RegExp("[xX].*log").test(value[0]) && /text/.test(value[2])); }); console.log("XorgLogAttList = " + XorgLogAttList.toSource()); if (XorgLogAttList.length == 0) { console.log("No Xorg.0.log attachments found.") return; } fillInChipMagicProcessAtts(); } /** * Opens a new tab with a query for the given text in the selected component * @param text to be searched for * @param component string with the component name (maybe latter regexp?) * @param product (optional) string with the product name * @return None * * old * long_desc=Xpress%20200&bug_status=NEW&bug_status=ASSIGNED * new * long_desc_type=substring&long_desc=Xpress%20200&bug_status=NEW&bug_status=ASSIGNED */ function queryInNewTab(text,component,product) { // Optional parameter if (product == null) { product = "Fedora"; } var url = "https://bugzilla.redhat.com/buglist.cgi?query_format=advanced"; if (product) { url += "&product="+product; } if (component) { url += "&component="+component; } if (text) { url += "&long_desc_type=substring&long_desc="+ text.replace(" ","%20"); } console.log("queryInNewTab: url = " + url); window.open(url); } function queryForSelection(component) { var text = window.getSelection().toString(); if (text.length < 1) { text = getClipboardText(); }; if (text.length > 0) { queryInNewTab(text, getComponent()); } } /** * Sends XMLRPC request * * @param url string with URL of the XML-RPC interface * @param data string with XML of the data to be sent * @param method string -- either 'post' or 'get' * @param callback function catching callback */ function sendRequest(url,data,method,callback) { //$.rpc(url, dataType, onLoadCallback, version); XMLHttpRequest({ method: method, url: url, headers: { 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey fixAttType XMLRPC', 'Accept': 'application/atom+xml,application/xml,text/xml', 'Content-type': 'text/xml' }, data: data, onload: callback }); } /** * Callback function for the XMLRPC request * * @param ret object with XMLHttpRequest response * with attributes: * + status -- int return code * + statusText * + responseHeaders * + responseText */ function callBack(ret) { if (ret.status != 200) { alert([ret.status,ret.statusText,ret.responseHeaders, ret.responseText]); } if (--reqCounter <= 0) { setTimeout("document.location.reload()",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, e.g. "text/plain" * */ function fixAttachById(id,type) { var msg = new XMLRPCMessage("bugzilla.updateAttachMimeType"); msg.addParameter({'attach_id':id, 'mime_type':type}); msg.addParameter(login); msg.addParameter(password); try { var ret = sendRequest(XMLRPCurl, msg.xml(),'post',callBack); } catch (e) { alert([e,ret]); } reqCounter++; } /** * Callback function for "Fix all attachments" button * @param list Array of * @return none */ function fixAllAttachments(list) { var tmpElem = {}; for(var i=0;iText").bind("click", function(event) { fixAttachById(row[1],"text/plain"); }); tElem.appendChild(t2Elem); $(curElem).parent().append("
"); $(curElem).parent().append(tElem); } function isOctetStream(element, index, array) { var inArray = ["application/octet-stream","text/x-log"]; return(inArray.indexOf(element[2]) != -1); } //=========================== /** * Find the next (or previous) sibling element of given tagName * starting from given element. * * @param startElement element from which to start searching * @param tagName string tagName of the searched for element (case insensitive) * @param forward boolean optional should we search forward or backward? * @return element of the given tagName or null */ function findNextSiblingByTagName(startElement,tagName,forward) { if (forward === null) { // missing optional argument forward = true; } var tempElement = startElement; tagName = tagName.toUpperCase(); while (tempElement && tempElement.tagName != tagName) { if (forward) { tempElement = tempElement.nextSibling; } else { tempElement = tempElement.previousSibling; } } return tempElement; } /** * Select option with given label on the