From 3a4f8dc7980ddd9a18a5bf87a4374ef57647d69f Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Sat, 26 Mar 2011 17:46:59 -0400 Subject: Do not assign an anchor to an attachment flag if it already has one. Fix for https://bitbucket.org/ehsan/bugzilla-tweaks/issue/4/attachment-flag-link-doesnt-correctly-get --- data/js/bug-page-mod.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data/js/bug-page-mod.js b/data/js/bug-page-mod.js index a75e776..561dda8 100644 --- a/data/js/bug-page-mod.js +++ b/data/js/bug-page-mod.js @@ -703,7 +703,9 @@ AttachmentFlagHandlerCtor.prototype = { if (!(id in this._interestingFlags)) continue; for (var j = 0; j < this._interestingFlags[id].length; ++j) { - if (flag.equals(this._interestingFlags[id][j])) { + // Take care to not assign an anchor to a flag which already has one + if (flag.equals(this._interestingFlags[id][j]) && + !("anchor" in this._interestingFlags[id][j])) { // found an interesting flag this._interestingFlags[id][j].anchor = this.anchorName; anchorsCreated.push(this.anchorName); @@ -1170,7 +1172,7 @@ function tbplbotSpamCollapser(d) { a.href = "#"; a.addEventListener("click", function(e) { e.preventDefault(); - var win = d.defaultView.wrappedJSObject; + var win = d.defaultView; var comments = d.querySelectorAll(".bz_comment"); for (var i = 0; i < comments.length; ++i) { var comment = comments[i]; -- cgit From 195a45e8a52a5663cc9678ae295a279712544f36 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 26 Apr 2011 14:26:19 -0400 Subject: Correct the attachment linkification based on the changes in Bugzilla 4.0 --- data/js/bug-page-mod.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/data/js/bug-page-mod.js b/data/js/bug-page-mod.js index 561dda8..596e2c7 100644 --- a/data/js/bug-page-mod.js +++ b/data/js/bug-page-mod.js @@ -630,11 +630,18 @@ AttachmentFlagHandlerCtor.prototype = { if (!(attachmentID in this._interestingFlags)) { this._interestingFlags[attachmentID] = []; } + var text = ""; + var previousText = ""; + var previousEl = null; for (var el = item[1].firstChild; el.nextSibling; el = el.nextSibling) { - if (el.nodeType != el.TEXT_NODE) - continue; - var text = trimContent(el).replace('\u2011', '-', 'g'); - if (!text) + var thisText = trimContent(el).replace('\u2011', '-', 'g'); + text += thisText; + if (this._reParsePartToLinkify.test(thisText)) { + previousText = thisText; + previousEl = el; + } + if (el.nodeType != el.ELEMENT_NODE || + el.localName.toLowerCase() != "br") continue; match = this._reParseInterestingFlag.exec(text); if (match) { @@ -666,22 +673,25 @@ AttachmentFlagHandlerCtor.prototype = { // try to put the flag name and type part in a span which we will // use in setupLinks to inject links into. - match = this._reLinkifyInterestingFlag.exec(text); + match = this._reLinkifyInterestingFlag.exec(previousText); if (match) { - el.textContent = match[1]; + previousEl.textContent = match[1]; if (match[3]) { var textNode = doc.createTextNode(match[3]); - el.parentNode.insertBefore(textNode, el.nextSibling); + previousEl.parentNode.insertBefore(textNode, previousEl.nextSibling); } var span = doc.createElement("span"); span.textContent = match[2]; - el.parentNode.insertBefore(span, el.nextSibling); + previousEl.parentNode.insertBefore(span, previousEl.nextSibling); flag.placeholder = span; } this._interestingFlags[attachmentID].push(new AttachmentFlag(flag)); } + text = ""; + previousText = ""; + previousEl = null; } } } @@ -756,8 +766,9 @@ AttachmentFlagHandlerCtor.prototype = { return "attachflag" + this._counter; }, _reParseRequest: /^(.+)([\?\-\+])(\((.+)@.+\))?$/, + _reParsePartToLinkify: /^\s*:\s+.+[\-\+\?](\s*\()?\s*$/, _reParseInterestingFlag: /^(.+):\s+(.+)(([\-\+])|\?(\s+(\((.+)\)))?)$/, - _reLinkifyInterestingFlag: /^(.+:\s+)(.+[\-\+\?])(\s+\(.+\))?$/, + _reLinkifyInterestingFlag: /^(\s*:\s+)(.+[\-\+\?])(\s*\(\s*)?$/, _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i, _reAttachmentFlagName: /^Attachment\s+#(\d+)\s+Flags$/i }; -- cgit From 74d114c5558ea9d17b86bb74831be335c976c643 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 26 Apr 2011 15:02:15 -0400 Subject: Correct the linkification of flags based on the changes in Bugzilla 4.0 --- data/js/bug-page-mod.js | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/data/js/bug-page-mod.js b/data/js/bug-page-mod.js index 596e2c7..96dbbf9 100644 --- a/data/js/bug-page-mod.js +++ b/data/js/bug-page-mod.js @@ -137,29 +137,27 @@ function tweakBugzilla(d) { } var flagCounter = 1; function findFlag(item) { - function lookup(name) { - name = name.replace('\u2011', '-', 'g'); - for (var i = 0; i < flagNames.length; ++i) { - var quotedFlagName = flagNames[i].replace('.', '\\.', 'g') - .replace('\u2011', '-', 'g'); - if ((new RegExp('^' + quotedFlagName)).test(name)) { - return [flagNames[i]]; + function lookup(names) { + names = names.split(", "); + var results = []; + for (var j = 0; j < names.length; ++j) { + var name = names[j].replace('\u2011', '-', 'g'); + for (var i = 0; i < flagNames.length; ++i) { + var quotedFlagName = flagNames[i].replace('.', '\\.', 'g') + .replace('\u2011', '-', 'g'); + if ((new RegExp('^' + quotedFlagName)).test(name)) { + results.push(flagNames[i]); + break; + } } } - return []; + return results; } var base = item[4] ? 2 : 0; // handle normal flags - if (trimContent(item[base]) == 'Flag') { - var result = []; - var tmp = lookup(trimContent(item[base + 1])); - if (tmp.length) { - result.push(tmp[0]); - } - tmp = lookup(trimContent(item[base + 2])); - if (tmp.length) { - result.push(tmp[0]); - } + if (trimContent(item[base]) == 'Flags') { + var result = lookup(trimContent(item[base + 1])). + concat(lookup(trimContent(item[base + 2]))); return result; } // handle special pseudo-flags -- cgit From 89f9e8aac15e6572293bada0a27335111d67403e Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Tue, 26 Apr 2011 15:28:47 -0400 Subject: Bump the version number to 1.10 --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 679e656..78f985b 100644 --- a/package.json +++ b/package.json @@ -14,5 +14,8 @@ "Heather Arthur (http://harthur.wordpress.com/) ", "Steve Fink (http://blog.mozilla.com/sfink/) " ], - "url": "https://fedorahosted.org/bugzilla-triage-scripts/", + "url": "http://ehsanakhgari.org/mozilla/extensions/firefox/bugzilla-tweaks", + "version": "1.10", + "fullName": "Bugzilla Tweaks", + "id": "jid0-qBnIpLfDFa4LpdrjhAC6vBqN20Q" } -- cgit From 3fe9f14f10381242a193d91f7dc8ea0307091f8e Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 25 Mar 2011 01:17:49 +0100 Subject: Working on cutting down lines from bug-page-mod.js --- data/js/bug-page-mod.js | 1206 -------------------------------------- data/js/cc-context.js | 8 - data/js/checkin-context.js | 11 - data/js/urltest.js | 4 - data/lib/addNewLinks.js | 60 ++ data/lib/bug-page-mod.js | 1002 +++++++++++++++++++++++++++++++ data/lib/cc-context.js | 8 + data/lib/checkin-context.js | 11 + data/lib/preprocessDuplicates.js | 120 ++++ data/lib/rhbzpage.js | 2 +- data/lib/urltest.js | 4 + data/lib/util.js | 8 +- data/lib/viewSource.js | 100 ++++ lib/libbugzilla.js | 2 +- lib/logger.js | 3 +- lib/main.js | 16 +- package.json | 7 +- 17 files changed, 1325 insertions(+), 1247 deletions(-) delete mode 100644 data/js/bug-page-mod.js delete mode 100644 data/js/cc-context.js delete mode 100644 data/js/checkin-context.js delete mode 100644 data/js/urltest.js create mode 100644 data/lib/addNewLinks.js create mode 100644 data/lib/bug-page-mod.js create mode 100644 data/lib/cc-context.js create mode 100644 data/lib/checkin-context.js create mode 100644 data/lib/preprocessDuplicates.js create mode 100644 data/lib/urltest.js create mode 100644 data/lib/viewSource.js diff --git a/data/js/bug-page-mod.js b/data/js/bug-page-mod.js deleted file mode 100644 index 96dbbf9..0000000 --- a/data/js/bug-page-mod.js +++ /dev/null @@ -1,1206 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Bugzilla Tweaks. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Johnathan Nightingale - * Ehsan Akhgari - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -function tweakBugzilla(d) { - // run on both bugzilla.m.o and bugzilla-stage-tip.m.o - if (!onBugzillaPage(d.URL)) - return; - - // Put the quicksearch text in the quicksearch boxes - quicksearchHandler(d); - - if (!d.getElementById("comments")) // don't process the mid-air collision pages - return; - - // Strip "Bug " from titles for better tab readability - if (/^Bug /.test(d.title)) - d.title = d.title.slice(4); - - // After POSTing, redirect with a GET back to the same bug - if (/\/(process_bug|attachment|post_bug).cgi$/.test(d.location.href)) { - var bug = getBugNumber(d); - if (bug) { - var url = d.location.href; - url = url.replace("process_bug.cgi", "show_bug.cgi"); - url = url.replace("attachment.cgi", "show_bug.cgi"); - url = url.replace("post_bug.cgi", "show_bug.cgi"); - url += "?id=" + bug; - d.defaultView.history.replaceState(null, "", url); - d.title = bug + " - " + d.getElementById("short_desc_nonedit_display").textContent; - } - } - - // Make the comment box bigger - var commentBox = d.querySelector("#comment"); - if (commentBox) - commentBox.rows=20; - - addNewLinks(d); - - attachmentDiffLinkify(d); - - viewAttachmentSource(d); - - // Mark up history along right hand edge - var historyLink = d.querySelector("link[title='Bug Activity']"); - if (!historyLink) - return; - - // Add our own style for bugzilla-tweaks - var style = d.createElement("style"); - style.setAttribute("type", "text/css"); - style.appendChild(d.createTextNode( - ".bztw_history { border: none; font-weight: normal; width: 58em; margin-left: 5em; }" + - ".bztw_inlinehistory { font-weight: normal; width: 56em; }" + - ".bztw_history .old, .bztw_inlinehistory .old { text-decoration: line-through; }" + - ".bztw_history .sep:before { content: \" \"; }" + - ".bztw_unconfirmed { font-style: italic; }" + - "tr.bz_tr_obsolete.bztw_plusflag { display: table-row !important; }" + - '.bztw_historyitem + .bztw_historyitem:before { content: "; "; }' - )); - d.getElementsByTagName("head")[0].appendChild(style); - style = d.createElement("style"); - style.setAttribute("type", "text/css"); - style.id = "bztw_cc"; - style.appendChild(d.createTextNode( - ".bztw_cc { display: none; }" + - '.bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: ""; }' + - '.bztw_historyitem:not([class~="bztw_cc"]) ~ .bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: "; "; }' - )); - d.getElementsByTagName("head")[0].appendChild(style); - - var userNameCache = {}; - function getUserName(email) { - if (email in userNameCache) { - return userNameCache[email]; - } - var emailLink = d.querySelectorAll("a.email"); - for (var i = 0; i < emailLink.length; ++i) { - if (emailLink[i].href == "mailto:" + email) { - return userNameCache[email] = htmlEncode(trimContent(emailLink[i])); - } - } - return email; - } - - // collect the flag names - var flagNames = [], flags = {}, flagOccurrences = {}; - var flagRows = d.querySelectorAll("#flags tr"); - for (var i = 0; i < flagRows.length; ++i) { - var item = flagRows[i].querySelectorAll("td"); - if (!item[1]) - continue; - var name = trimContent(item[1]).replace('\u2011', '-', 'g'); - flagNames.push(name); - flags[name] = item[1]; - } - flagRows = d.querySelectorAll(".field_label[id^=field_label_cf_]"); - for (var i = 0; i < flagRows.length; ++i) { - var name = trimContent(flagRows[i]).replace(/\:$/, '') - .replace('\u2011', '-', 'g'); - flagNames.push(name); - flags[name] = flagRows[i]; - } - var flagCounter = 1; - function findFlag(item) { - function lookup(names) { - names = names.split(", "); - var results = []; - for (var j = 0; j < names.length; ++j) { - var name = names[j].replace('\u2011', '-', 'g'); - for (var i = 0; i < flagNames.length; ++i) { - var quotedFlagName = flagNames[i].replace('.', '\\.', 'g') - .replace('\u2011', '-', 'g'); - if ((new RegExp('^' + quotedFlagName)).test(name)) { - results.push(flagNames[i]); - break; - } - } - } - return results; - } - var base = item[4] ? 2 : 0; - // handle normal flags - if (trimContent(item[base]) == 'Flags') { - var result = lookup(trimContent(item[base + 1])). - concat(lookup(trimContent(item[base + 2]))); - return result; - } - // handle special pseudo-flags - return lookup(trimContent(item[base])); - } - - var DataStore = new DataStoreCtor(d); - - var AttachmentFlagHandler = new AttachmentFlagHandlerCtor(); - AttachmentFlagHandler.determineInterestingFlags(d); - - var CheckinComment = new CheckinCommentCtor(); - CheckinComment.initialize(d, AttachmentFlagHandler._interestingFlags); - - var iframe = d.createElement('iframe'); - iframe.src = historyLink.href; - iframe.style.display = "none"; - iframe.addEventListener("load", function() { - preprocessDuplicateMarkers(d, iframe.contentDocument); - - var historyItems = iframe.contentDocument.querySelectorAll('#bugzilla-body tr'); - var commentTimes = d.querySelectorAll('.bz_comment_time'); - - // Sometimes the history will stack several changes together, - // and we'll want to append the data from the Nth item to the - // div created in N-1 - var i=0, j=0, flagsFound; - for (; i < historyItems.length; i++) { - var item = historyItems[i].querySelectorAll("td"); - if (!item[1]) - continue; - - var reachedEnd = false; - for (; j < commentTimes.length; j++) { - if (trimContent(item[1]) > trimContent(commentTimes[j])) { - if (j < commentTimes.length - 1) { - continue; - } else { - reachedEnd = true; - } - } - - var commentHead = commentTimes[j].parentNode; - - var mainUser = commentHead.querySelector(".bz_comment_user a.email") - .href - .substr(7); - var user = trimContent(item[0]); - var mainTime = trimContent(commentTimes[j]); - var time = trimContent(item[1]); - var inline = (mainUser == user && time == mainTime); - - var currentDiv = d.createElement("div"); - var userPrefix = ''; - if (inline) { - // assume that the change was made by the same user - commentHead.appendChild(currentDiv); - currentDiv.setAttribute("class", "bztw_inlinehistory"); - } else { - // the change was made by another user - if (!reachedEnd) { - var parentDiv = commentHead.parentNode; - if (parentDiv.previousElementSibling && - parentDiv.previousElementSibling.className.indexOf("bztw_history") >= 0) { - currentDiv = parentDiv.previousElementSibling; - } else { - parentDiv.parentNode.insertBefore(currentDiv, parentDiv); - } - } else { - var parentDiv = commentHead.parentNode; - if (parentDiv.nextElementSibling && - parentDiv.nextElementSibling.className.indexOf("bztw_history") >= 0) { - currentDiv = parentDiv.nextElementSibling; - } else { - parentDiv.parentNode.appendChild(currentDiv); - } - } - currentDiv.setAttribute("class", "bz_comment bztw_history"); - userPrefix += "" + - getUserName(trimContent(item[0])) + ": "; - } - // check to see if this is a flag setting - flagsFound = findFlag(item); - for (var idx = 0; idx < flagsFound.length; ++idx) { - var flag = flagsFound[idx]; - flagOccurrences[flag] = 'flag' + flagCounter; - if (inline) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", "flag" + flagCounter); - commentHead.insertBefore(anchor, commentHead.firstChild); - } else { - userPrefix += ''; - } - ++flagCounter; - } - - var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); - if (inline) { - for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", attachmentFlagAnchors[idx]); - commentHead.insertBefore(anchor, commentHead.firstChild); - } - } else { - userPrefix += attachmentFlagAnchors.map(function(name) '').join(""); - } - - var ccOnly = (trimContent(item[2]) == 'CC'); - var ccPrefix = ccOnly ? '' : - '', - ccSuffix = ''; - var html = userPrefix + - ccPrefix + - transformType(trimContent(item[2]), d, trimContent(item[3]), - trimContent(item[4])) + ": " + - formatTransition(trimContent(item[3]), trimContent(item[4]), - trimContent(item[2]), d, iframe.contentDocument); - - var nextItemsCount = item[0].rowSpan; - for (var k = 1; k < nextItemsCount; ++k) { - ccOnly = false; - item = historyItems[++i].querySelectorAll("td") - ccPrefix = (trimContent(item[0]) == 'CC') ? - '' : ''; - // avoid showing a trailing semicolon if the previous entry wasn't a CC and this one is - var prefix = ccSuffix + ccPrefix; - // check to see if this is a flag setting - flagsFound = findFlag(item); - for (var idx = 0; idx < flagsFound.length; ++idx) { - var flag = flagsFound[idx]; - flagOccurrences[flag] = 'flag' + flagCounter; - if (inline) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", "flag" + flagCounter); - commentHead.insertBefore(anchor, commentHead.firstChild); - } else { - prefix += ''; - } - ++flagCounter; - } - - var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); - if (inline) { - for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", attachmentFlagAnchors[idx]); - commentHead.insertBefore(anchor, commentHead.firstChild); - } - } else { - prefix += attachmentFlagAnchors.map(function(name) '').join(""); - } - - html += prefix + - transformType(trimContent(item[0]), d, trimContent(item[1]), - trimContent(item[2])) + ": " + - formatTransition(trimContent(item[1]), trimContent(item[2]), - trimContent(item[0]), d, iframe.contentDocument); - } - html += ccSuffix; - if (ccOnly) { - html = '
' + html + '
'; - } else { - html = '
' + html + '
'; - } - currentDiv.innerHTML += html; - break; - } - } - - handleEmptyCollapsedBoxes(d); - - // Set the latest flag links if necessary - for (var flagName in flagOccurrences) { - flags[flagName].innerHTML = '' - + flags[flagName].innerHTML + ''; - } - - AttachmentFlagHandler.setupLinks(d); - },true); - d.body.appendChild(iframe); - - tbplbotSpamCollapser(d); -} - -var TransformValues = { - linkifyURLs: function (str) { - return str.replace(/((https?|ftp)\:\/\/[\S]+)/g, '$1'); - }, - linkifyBugAndCommentNumbers: function (str) { - return str.replace(/(bug )(\d+) (comment )(\d+)/gi, '$1\n$2 $3\n$4'); - }, - linkifyCommentNumbers: function (str) { - return str.replace(/(comment (\d+))/gi, '$1'); - }, - linkifyBugNumbers: function (str) { - return str.replace(/(bug (\d+))/gi, '$1'); - }, - linkifyDependencies: function (str, type, doc, histDoc) { - switch (type) { - case "Blocks": - case "Depends on": - case "Duplicate": - str = str.replace(/\d+/g, function(str) { - var link = histDoc.querySelector("a[href='show_bug.cgi?id=" + str + "']"); - if (link) { - var class_ = ''; - if (/bz_closed/i.test(link.className)) { - class_ += 'bz_closed '; - } else if (/bztw_unconfirmed/i.test(link.className)) { - class_ += 'bztw_unconfirmed '; - } - var parent = link.parentNode; - if (parent) { - if (parent.tagName.toLowerCase() == "i") { - class_ += 'bztw_unconfirmed '; - } - if (/bz_closed/i.test(parent.className)) { - class_ += 'bz_closed '; - } - } - str = applyClass(class_, - '' + htmlEncode(str) + ''); - } - return str; - }); - } - return str; - } -}; - -function transform(str, type, doc, histDoc) { - for (var funcname in TransformValues) { - var func = TransformValues[funcname]; - str = func.call(null, str, type, doc, histDoc); - } - return str -} - -var TransformTypes = { - linkifyAttachments: function (str, doc) { - return str.replace(/(Attachment #(\d+))/g, function (str, x, id) { - var link = doc.querySelector("a[href='attachment.cgi?id=" + id + "']"); - if (link) { - var class_ = ''; - if (/bz_obsolete/i.test(link.className)) { - class_ += 'bz_obsolete '; - } - var parent = link.parentNode; - if (parent && /bz_obsolete/i.test(parent.className)) { - class_ += 'bz_obsolete '; - } - if (link.querySelector(".bz_obsolete")) { - class_ += 'bz_obsolete '; - } - str = applyClass(class_, - '' + htmlEncode(str) + ''); - } - return str; - }); - }, - changeDependencyLinkTitles: function (str, doc, old, new_) { - switch (str) { - case "Blocks": - case "Depends on": - if (old.length && !new_.length) { // if the dependency was removed - str = "No longer " + str[0].toLowerCase() + str.substr(1); - } - break; - } - return str; - } -}; - -function transformType(str, doc, old, new_) { - for (var funcname in TransformTypes) { - var func = TransformTypes[funcname]; - str = func.call(null, str, doc, old, new_); - } - return str; -} - -// new is a keyword, which makes this function uglier than I'd like -function formatTransition(old, new_, type, doc, histDoc) { - if (old.length) { - old = transform(htmlEncode(old), type, doc, histDoc); - var setOldStyle = true; - switch (type) { - case "Blocks": - case "Depends on": - setOldStyle = false; - break; - } - if (setOldStyle) { - old = '' + old + ''; - } - } - if (new_.length) { - new_ = '' + transform(htmlEncode(new_), type, doc, histDoc) + ''; - } - var mid = ''; - if (old.length && new_.length) { - mid = ' '; - } - return old + mid + new_; -} - -function trimContent(el) { - return el.textContent.trim(); -} - -function AttachmentFlag(flag) { - for (var name in flag) - this[name] = flag[name]; -} -AttachmentFlag.prototype = { - equals: function(flag) { - if (this.type != flag.type || - this.name != flag.name || - this.setter != flag.setter || - ("requestee" in this && !("requestee" in flag)) || - ("requestee" in flag && !("requestee" in this))) - return false; - return this.requestee == flag.requestee; - } -}; - -var reAttachmentDiff = /attachment\.cgi\?id=(\d+)&action=diff$/i; -var reviewBoardUrlBase = "http://reviews.visophyte.org/"; - -/** - * Whenever we find a patch with a diff, insert an additional link to asuth's - * review board magic. - */ -function attachmentDiffLinkify(doc) { - var bug_id = getBugNumber(doc); - - var table = doc.getElementById("attachment_table"); - if (!table) - return; - var rows = table.querySelectorAll("tr"); - for (var i = 0; i < rows.length; ++i) { - var item = rows[i].querySelectorAll("td"); - if (item.length != 3) - continue; - // get the ID of the attachment - var links = item[2].querySelectorAll("a"); - if (links.length != 2) - continue; - var match = reAttachmentDiff.exec(links[1].href); - if (match) { - var attach_id = match[1]; - var parentNode = links[1].parentNode; - parentNode.appendChild(doc.createTextNode(" | ")); - var linkNode = doc.createElement("a"); - linkNode.href = reviewBoardUrlBase + "r/bzpatch/bug" + bug_id + "/attach" + attach_id + "/"; - linkNode.textContent = "Review"; - parentNode.appendChild(linkNode); - } - } -} - -var reAttachmentType = /,\s+([^ )]*)[;)]/; - -function viewAttachmentSource(doc) { - function addLink(elem, title, href) { - if (elem.textContent.match(/[\S]/)) { - elem.appendChild(doc.createTextNode(" | ")); - } - var link = doc.createElement("a"); - link.href = href; - link.textContent = title; - elem.appendChild(link); - } - var table = doc.getElementById("attachment_table"); - if (!table) - return; - var rows = table.querySelectorAll("tr"); - for (var i = 0; i < rows.length; ++i) { - var items = rows[i].querySelectorAll("td"); - if (items.length != 3) - continue; - var links = items[0].querySelectorAll("a"); - if (links.length == 0) - continue; - var attachHref = links[0].href; - // get the type of the attachment - var span = items[0].querySelector(".bz_attach_extra_info"); - if (!span) - continue; - var typeName = null; - try { - // Match mime type followed by ";" (charset) or ")" (no charset) - typeName = span.textContent.match(reAttachmentType)[1]; - typeName = typeName.split(";")[0]; // ignore charset following type - } catch (e) {} - if (typeName == "application/java-archive" || - typeName == "application/x-jar") { - // Due to the fix for bug 369814, only zip files with this special - // mime type can be used with the jar: protocol. - // http://hg.mozilla.org/mozilla-central/rev/be54f6bb9e1e - addLink(items[2], "JAR Contents", "jar:" + attachHref + "!/"); - // https://bugzilla.mozilla.org/show_bug.cgi?id=369814#c5 has more possible mime types for zips? - } else if (typeName == "application/zip" || - typeName == "application/x-zip-compressed" || - typeName == "application/x-xpinstall") { - addLink(items[2], "Static ZIP Contents", "jar:" + attachHref + "!/"); - } else if (typeName != "text/plain" && - typeName != "patch" && - // Other types that Gecko displays like text/plain - // http://mxr.mozilla.org/mozilla-central/source/parser/htmlparser/public/nsIParser.h - typeName != "text/css" && - typeName != "text/javascript" && - typeName != "text/ecmascript" && - typeName != "application/javascript" && - typeName != "application/ecmascript" && - typeName != "application/x-javascript" && - // Binary image types for which the "source" is not useful - typeName != "image/gif" && - typeName != "image/png" && - typeName != "image/jpeg") { - addLink(items[2], "Source", "view-source:" + attachHref); - } - } -} - -function quicksearchHandler(doc) { - var win = doc.defaultView; - var match = /quicksearch=([^&]+)/i.exec(win.location.search); - if (match) { - var quicksearch = unescape(match[1].replace('+', ' ', 'g')); - var quicksearchBox = doc.querySelectorAll("input[name=quicksearch]"); - if (quicksearchBox) { - for (var i = 0; i < quicksearchBox.length; ++i) { - quicksearchBox[i].value = quicksearch; - } - } - } -} - -function AttachmentFlagHandlerCtor() { - this._db = {}; - this._interestingFlags = {}; -} -AttachmentFlagHandlerCtor.prototype = { - determineInterestingFlags: function (doc) { - var table = doc.getElementById("attachment_table"); - if (!table) - return; - var rows = table.querySelectorAll("tr"); - for (var i = 0; i < rows.length; ++i) { - var item = rows[i].querySelectorAll("td"); - if (item.length != 3 || - item[1].className.indexOf("bz_attach_flags") < 0 || - trimContent(item[1]) == "no flags") - continue; - // get the ID of the attachment - var link = item[0].querySelector("a"); - if (!link) - continue; - var match = this._reAttachmentHref.exec(link.href); - if (match) { - var attachmentID = match[1]; - if (!(attachmentID in this._interestingFlags)) { - this._interestingFlags[attachmentID] = []; - } - var text = ""; - var previousText = ""; - var previousEl = null; - for (var el = item[1].firstChild; el.nextSibling; el = el.nextSibling) { - var thisText = trimContent(el).replace('\u2011', '-', 'g'); - text += thisText; - if (this._reParsePartToLinkify.test(thisText)) { - previousText = thisText; - previousEl = el; - } - if (el.nodeType != el.ELEMENT_NODE || - el.localName.toLowerCase() != "br") - continue; - match = this._reParseInterestingFlag.exec(text); - if (match) { - var flag = {}; - flag.setter = match[1]; - flag.name = match[2]; - if (match[4] == "+" || match[4] == "-") { - flag.type = match[4]; - } else { - flag.type = "?"; - if (match[7]) { - flag.requestee = match[7]; - } - } - - // always show the obsolete attachments with a + flag - if (flag.type == "+") { - var parent = link.parentNode; - while (parent) { - if (parent.tagName.toLowerCase() == "tr") { - if (/bz_tr_obsolete/i.test(parent.className)) { - parent.className += " bztw_plusflag"; - } - break; - } - parent = parent.parentNode; - } - } - - // try to put the flag name and type part in a span which we will - // use in setupLinks to inject links into. - match = this._reLinkifyInterestingFlag.exec(previousText); - if (match) { - previousEl.textContent = match[1]; - if (match[3]) { - var textNode = doc.createTextNode(match[3]); - previousEl.parentNode.insertBefore(textNode, previousEl.nextSibling); - } - var span = doc.createElement("span"); - span.textContent = match[2]; - previousEl.parentNode.insertBefore(span, previousEl.nextSibling); - - flag.placeholder = span; - } - - this._interestingFlags[attachmentID].push(new AttachmentFlag(flag)); - } - text = ""; - previousText = ""; - previousEl = null; - } - } - } - }, - handleItem: function (name, item) { - var anchorsCreated = []; - var base = item[4] ? 2 : 0; - var what = trimContent(item[base]); - var match = this._reAttachmentFlagName.exec(what); - if (match) { - var id = match[1]; - if (!(id in this._db)) { - this._db[id] = []; - } - name = name.split('@')[0]; // convert the name to the fraction before the @ - var added = this._parseData(name, trimContent(item[base + 2])); - for (var i = 0; i < added.length; ++i) { - var flag = added[i]; - if (!(id in this._interestingFlags)) - continue; - for (var j = 0; j < this._interestingFlags[id].length; ++j) { - // Take care to not assign an anchor to a flag which already has one - if (flag.equals(this._interestingFlags[id][j]) && - !("anchor" in this._interestingFlags[id][j])) { - // found an interesting flag - this._interestingFlags[id][j].anchor = this.anchorName; - anchorsCreated.push(this.anchorName); - this._counter++; - break; - } - } - } - } - return anchorsCreated; - }, - setupLinks: function (doc) { - for (var id in this._interestingFlags) { - for (var i = 0; i < this._interestingFlags[id].length; ++i) { - var flag = this._interestingFlags[id][i]; - if ("placeholder" in flag && - "anchor" in flag) { - var link = doc.createElement("a"); - link.href = "#" + flag.anchor; - link.textContent = flag.placeholder.textContent; - flag.placeholder.replaceChild(link, flag.placeholder.firstChild); - } - } - } - }, - _parseData: function (name, str) { - var items = str.replace('\u2011', '-', 'g').split(', '), flags = []; - for (var i = 0; i < items.length; ++i) { - if (!items[i].length) - continue; - - var match = this._reParseRequest.exec(items[i]); - if (match) { - var flag = {}; - flag.name = match[1]; - flag.setter = name; - if (match[4]) { - flag.requestee = match[4]; - } - flag.type = match[2]; - flags.push(new AttachmentFlag(flag)); - } - } - return flags; - }, - _counter: 1, - get anchorName() { - return "attachflag" + this._counter; - }, - _reParseRequest: /^(.+)([\?\-\+])(\((.+)@.+\))?$/, - _reParsePartToLinkify: /^\s*:\s+.+[\-\+\?](\s*\()?\s*$/, - _reParseInterestingFlag: /^(.+):\s+(.+)(([\-\+])|\?(\s+(\((.+)\)))?)$/, - _reLinkifyInterestingFlag: /^(\s*:\s+)(.+[\-\+\?])(\s*\(\s*)?$/, - _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i, - _reAttachmentFlagName: /^Attachment\s+#(\d+)\s+Flags$/i -}; - -function CheckinCommentCtor() { - this.bugNumber = null; - this.summarySpan = null; - this.checkinFlags = ""; -} -CheckinCommentCtor.prototype = { - initialize: function(doc, flags) { - this.bugNumber = getBugNumber(doc); - var summarySpan = doc.getElementById("short_desc_nonedit_display"); - if (summarySpan) { - this.summary = summarySpan.textContent; - } - var checkinFlagsMap = {}; - for (var id in flags) { - for (var i = 0; i < flags[id].length; ++i) { - var flag = flags[id][i]; - if (flag.type == "+") { - var name = flag.name; - if (name == "review") { - name = "r"; - } else if (name == "superreview") { - name = "sr"; - } else if (name == "ui-review") { - name = "ui-r"; - } else if (name == "feedback") { - name = "f"; - } - if (!(name in checkinFlagsMap)) { - checkinFlagsMap[name] = {}; - } - checkinFlagsMap[name][flag.setter]++; - } - } - } - var flagsOrdered = []; - for (var name in checkinFlagsMap) { - flagsOrdered.push(name); - } - flagsOrdered.sort(function (a, b) { - function convertToNumber(x) { - switch (x) { - case "f": - return -4; - case "r": - return -3; - case "sr": - return -2; - case "ui-r": - return -1; - default: - return 0; - } - } - var an = convertToNumber(a); - var bn = convertToNumber(b); - if (an == 0 && bn == 0) { - return a < b ? -1 : (a = b ? 0 : 1); - } else { - return an - bn; - } - }); - var checkinFlags = []; - for (var i = 0; i < flagsOrdered.length; ++i) { - var name = flagsOrdered[i]; - var flag = name + "="; - var setters = []; - for (var setter in checkinFlagsMap[name]) { - setters.push(setter); - } - flag += setters.join(","); - checkinFlags.push(flag); - } - this.checkinFlags = checkinFlags.join(" "); - if (this.isValid()) { - var div = doc.createElement("div"); - div.setAttribute("style", "display: none;"); - div.id = "__bz_tw_checkin_comment"; - div.appendChild(doc.createTextNode(this.toString())); - doc.body.appendChild(div); - } - }, - isValid: function() { - return this.bugNumber != null && - this.summary != null; - }, - toString: function() { - if (!this.isValid()) { - return ""; - } - var message = "Bug " + this.bugNumber + " - " + this.summary; - if (this.checkinFlags.length) { - message += "; " + this.checkinFlags; - } - return message; - } -}; - -function DataStoreCtor(doc) { - this.storage = doc.defaultView.localStorage; - this.data = {}; - this.bugNumber = null; - function visualizeStoredData() { - var data = ""; - for (var i = 0; i < window.localStorage.length; ++i) { - var key = window.localStorage.key(i); - data += key + ": " + JSON.parse(window.localStorage.getItem(key).toString()).toSource() + "\n"; - } - open("data:text/html,
" + escape(htmlEncode(data)) + "
"); - } - function clearStoredData() { - var count = window.localStorage.length; - if (count > 0) { - if (window.confirm("You currently have data stored for " + count + " bugs.\n\n" + - "Are you sure you want to clear this data? This action cannot be undone.")) { - window.localStorage.clear(); - } - } else { - alert("You don't have any data stored about your bugs"); - } - } - var script = doc.createElement("script"); - script.appendChild(doc.createTextNode(visualizeStoredData.toSource() + - clearStoredData.toSource() + - htmlEncode.toSource())); - doc.body.appendChild(script); - this.initialize(doc); -} - -DataStoreCtor.prototype = { - initialize: function(doc) { - this.bugNumber = getBugNumber(doc); - var data = this._ensureEntry(this.bugNumber, this.data); - // last visited date - data.visitedTime = (new Date()).getTime(); - // last comment count - data.commentCount = doc.querySelectorAll(".bz_comment").length; - // last status of bug flags - var flags = this._ensureEntry("flags", data); - var flagRows = doc.querySelectorAll("#flags tr"); - for (var i = 0; i < flagRows.length; ++i) { - var flagCols = flagRows[i].querySelectorAll("td"); - if (flagCols.length != 3) { - continue; - } - var flagName = trimContent(flagCols[1]); - var flagValue = flagCols[2].querySelector("select"); - if (flagValue) { - flagValue = flagValue.value; - } else { - continue; - } - flags[flagName] = flagValue; - } - flagRows = doc.querySelectorAll(".field_label[id^=field_label_cf_]"); - for (var i = 0; i < flagRows.length; ++i) { - var flagName = trimContent(flagRows[i]).replace(/:$/, ""); - var flagValue = flagRows[i].parentNode.querySelector("select"); - if (flagValue) { - flagValue = flagValue.value; - } else { - continue; - } - flags[flagName] = flagValue; - } - // last attachments - var attachmentTable = doc.getElementById("attachment_table"); - var attachmentRows = attachmentTable.querySelectorAll("tr"); - for (var i = 0; i < attachmentRows.length; ++i) { - var attachmentCells = attachmentRows[i].querySelectorAll("td"); - if (attachmentCells.length != 3) { - continue; - } - var link = attachmentCells[0].querySelector("a"); - var match = this._reAttachmentHref.exec(link.href); - if (match) { - var attachmentID = match[1]; - var attachment = this._ensureEntry("attachments", data); - var attachmentFlags = this._ensureArray(attachmentID, attachment); - for (var el = attachmentCells[1].firstChild; el.nextSibling; el = el.nextSibling) { - if (el.nodeType != el.TEXT_NODE) { - continue; - } - var text = trimContent(el); - if (!text) { - continue; - } - match = this._reParseInterestingFlag.exec(text); - if (match) { - var flag = {}; - flag.setter = match[1]; - flag.name = match[2]; - if (match[4] == "+" || match[4] == "-") { - flag.type = match[4]; - } else { - flag.type = "?"; - if (match[7]) { - flag.requestee = match[7]; - } - } - attachmentFlags.push(flag); - } - } - } - } - // Write data to storage - for (var key in this.data) { - this._ensure(key, this.storage, JSON.stringify(this.data[key])); - } - }, - _ensure: function(entry, obj, val) { - if (obj.toString().indexOf("[object Storage") >= 0) { - obj.setItem(entry, val); - } else { - if (typeof obj[entry] == "undefined") - obj[entry] = val; - return obj[entry]; - } - }, - _ensureEntry: function(entry, obj) { - return this._ensure(entry, obj, {}); - }, - _ensureArray: function(entry, obj) { - return this._ensure(entry, obj, []); - }, - _reParseInterestingFlag: /^(.+):\s+(.+)(([\-\+])|\?(\s+(\((.+)\)))?)$/, - _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i -}; - -function getBugNumber(doc) { - var idField = doc.querySelector("form[name=changeform] input[name=id]"); - if (idField) { - return idField.value; - } - return null; -} - -function getUserName(doc) { - var links = doc.querySelectorAll("#header .links li"); - var last = links[links.length - 1]; - if (last.innerHTML.indexOf("logout") >= 0) { - return trimContent(last.lastChild); - } - return null; -} - -function preprocessDuplicateMarkers(mainDoc, histDoc) { - var comments = mainDoc.querySelectorAll(".bz_comment"); - var reDuplicate = /^\s*\*\*\*\s+Bug\s+(\d+)\s+has\s+been\s+marked\s+as\s+a\s+duplicate\s+of\s+this\s+bug.\s+\*\*\*\s*$/i; - var row = 0; - var rows = histDoc.querySelectorAll("#bugzilla-body tr"); - for (var i = 1 /* comment 0 can never be a duplicate marker */; - i < comments.length; ++i) { - var textHolder = comments[i].querySelector(".bz_comment_text"); - var match = reDuplicate.exec(trimContent(textHolder)); - if (match) { - // construct the table row to be injected in histDoc - var bugID = match[1]; - var email = comments[i].querySelector(".bz_comment_user .email") - .href - .substr(7); - var link = textHolder.querySelector("a"); - var title = link.title; - var time = trimContent(comments[i].querySelector(".bz_comment_time")); - var what = 'Duplicate'; - var removed = ''; - var number = trimContent(comments[i].querySelector(".bz_comment_number")). - replace(/[^\d]+/g, ''); - var class_ = ''; - if (/bz_closed/i.test(link.className + " " + link.parentNode.className)) { - class_ += 'bz_closed '; - } - if (link.parentNode.tagName.toLowerCase() == 'i') { - class_ += 'bztw_unconfirmed '; - } - var added = '' + bugID + ''; - - // inject the table row - var reachedEnd = false; - for (; row < rows.length; ++row) { - var cells = rows[row].querySelectorAll("td"); - if (cells.length != 5) - continue; - if (time > trimContent(cells[1])) { - if (row < rows.length - 1) { - continue; - } else { - reachedEnd = true; - } - } - if (time == trimContent(cells[1])) { - cells[0].rowSpan++; - cells[1].rowSpan++; - var rowContents = [what, removed, added]; - var tr = histDoc.createElement("tr"); - rowContents.forEach(function (cellContents) { - var td = histDoc.createElement("td"); - td.innerHTML = cellContents; - tr.appendChild(td); - }); - if (row != rows.length - 1) { - rows[row].parentNode.insertBefore(tr, rows[row+1]); - } else { - rows[row].parentNode.appendChild(tr); - } - } else { - var rowContents = [email, time, what, removed, added]; - var tr = histDoc.createElement("tr"); - rowContents.forEach(function (cellContents) { - var td = histDoc.createElement("td"); - td.innerHTML = cellContents; - tr.appendChild(td); - }); - if (reachedEnd) { - rows[row].parentNode.appendChild(tr); - } else { - rows[row].parentNode.insertBefore(tr, rows[row]); - } - } - break; - } - - // remove the comment from the main doc - comments[i].parentNode.removeChild(comments[i]); - } - } -} - -function handleEmptyCollapsedBoxes(doc) { - // first, try to get the display style of a CC field (any would do) - var historyBoxes = doc.querySelectorAll(".bztw_history"); - for (var i = 0; i < historyBoxes.length; ++i) { - var box = historyBoxes[i]; - for (var j = 0; j < box.childNodes.length; ++j) { - var child = box.childNodes[j], found = true; - if (child.nodeType != child.ELEMENT_NODE) - continue; - if (child.className == "sep") { - // separators are insignificant - continue; - } else if (!/bztw_cc/.test(child.className)) { - found = false; - break; - } - } - if (found) { - box.className += " bztw_cc"; - } - } -} - -function applyClass(class_, html) { - return '' + html + ''; -} - -function htmlEncode(str) { - return str.replace('&', '&', 'g') - .replace('<', '<', 'g') - .replace('>', '>', 'g') - .replace('"', '"', 'g'); -} - -function addNewLinks(d) { - var product = d.querySelector("#field_container_product option[selected]"); - var component = d.querySelector("#component option[selected]"); - - if (product) { - var label = d.getElementById('field_container_product'); - var url = 'enter_bug.cgi?product=' + encodeURIComponent(product.value); - if (label) { - label.appendChild(d.createTextNode("(")); - var link = d.createElement('a'); - link.href = url; - link.textContent = "new"; - link.title = "File a new bug in the same Product"; - var span = d.createElement('span'); - span.appendChild(link); - label.appendChild(span); - label.appendChild(d.createTextNode(")")); - } - } - - if (product && component) { - var select = d.querySelector("select#component"); - var label = select.parentNode; - var url = 'enter_bug.cgi?product=' + encodeURIComponent(product.value) + '&component=' + encodeURIComponent(component.value); - if (label) { - label.appendChild(d.createTextNode("(")); - var link = d.createElement('a'); - link.href = url; - link.textContent = "new"; - link.title = "File a new bug in the same Product and Component"; - var span = d.createElement('span'); - span.appendChild(link); - label.appendChild(span); - label.appendChild(d.createTextNode(")")); - } - } -} - -function tbplbotSpamCollapser(d) { - var collapseExpandBox = d.querySelector(".bz_collapse_expand_comments"); - if (!collapseExpandBox) { - return; - } - var a = d.createElement("a"); - a.href = "#"; - a.addEventListener("click", function(e) { - e.preventDefault(); - var win = d.defaultView; - var comments = d.querySelectorAll(".bz_comment"); - for (var i = 0; i < comments.length; ++i) { - var comment = comments[i]; - try { - if (comment.querySelector(".bz_comment_user a.email").href.substr(7) == - "tbplbot@gmail.com") { - win.collapse_comment(comment.querySelector(".bz_collapse_comment"), - comment.querySelector(".bz_comment_text")); - } - } catch (e) { - continue; - } - } - return false; - }, false); - a.appendChild(d.createTextNode("Collapse All tbplbot Comments")); - var li = d.createElement("li"); - li.appendChild(a); - collapseExpandBox.appendChild(li); -} - -tweakBugzilla(document); diff --git a/data/js/cc-context.js b/data/js/cc-context.js deleted file mode 100644 index 38397a9..0000000 --- a/data/js/cc-context.js +++ /dev/null @@ -1,8 +0,0 @@ -on('click', function(node, data) { - var style = document.getElementById("bztw_cc"); - style.disabled = !style.disabled; -}); - -on('context', function(node) { - return onBugzillaPage(document.URL); -}); diff --git a/data/js/checkin-context.js b/data/js/checkin-context.js deleted file mode 100644 index 4d073be..0000000 --- a/data/js/checkin-context.js +++ /dev/null @@ -1,11 +0,0 @@ -on('click', function(node, data) { - var message = document.getElementById("__bz_tw_checkin_comment"); - postMessage(message.textContent); -}); - -on('context', function(node) { - if (!onBugzillaPage(document.URL)) - return false; - var message = document.getElementById("__bz_tw_checkin_comment"); - return !!message; -}); diff --git a/data/js/urltest.js b/data/js/urltest.js deleted file mode 100644 index a0dbabf..0000000 --- a/data/js/urltest.js +++ /dev/null @@ -1,4 +0,0 @@ -function onBugzillaPage(url) { - return /https:\/\/bugzilla(-[a-zA-Z]+)*\.mozilla\.org/.test(url) - || /https:\/\/landfill.*\.bugzilla\.org/.test(url); -} \ No newline at end of file diff --git a/data/lib/addNewLinks.js b/data/lib/addNewLinks.js new file mode 100644 index 0000000..7993e07 --- /dev/null +++ b/data/lib/addNewLinks.js @@ -0,0 +1,60 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Bugzilla Tweaks. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johnathan Nightingale + * Ehsan Akhgari + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +function addNewLinks(d) { + var product = d.querySelector("#field_container_product option[selected]"); + var component = d.querySelector("#component option[selected]"); + + if (product) { + var label = d.getElementById('field_container_product'); + var url = 'enter_bug.cgi?product=' + encodeURIComponent(product.value); + if (label) { + createDeadLink("file_new_bug_product", "new", label, + url, [], "parens"); + } + } + + if (product && component) { + var select = d.querySelector("select#component"); + var label = select.parentNode; + var url = 'enter_bug.cgi?product=' + encodeURIComponent(product.value) + + '&component=' + encodeURIComponent(component.value); + if (label) { + createDeadLink("file_new_bug_component", "new", label, url, [], "parens"); + } + } +} diff --git a/data/lib/bug-page-mod.js b/data/lib/bug-page-mod.js new file mode 100644 index 0000000..589a45f --- /dev/null +++ b/data/lib/bug-page-mod.js @@ -0,0 +1,1002 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Bugzilla Tweaks. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johnathan Nightingale + * Ehsan Akhgari + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +function tweakBugzilla(d) { + // run on both bugzilla.m.o and bugzilla-stage-tip.m.o + if (!onBugzillaPage(d.URL)) + return; + + // Put the quicksearch text in the quicksearch boxes + quicksearchHandler(d); + + if (!d.getElementById("comments")) // don't process the mid-air collision pages + return; + + // Make the comment box bigger + var commentBox = d.querySelector("#comment"); + if (commentBox) + commentBox.rows=20; + + addNewLinks(d); + + attachmentDiffLinkify(d); + + viewAttachmentSource(d); + + // Mark up history along right hand edge + var historyLink = d.querySelector("link[title='Bug Activity']"); + if (!historyLink) + return; + + // Add our own style for bugzilla-tweaks + var style = d.createElement("style"); + style.setAttribute("type", "text/css"); + style.appendChild(d.createTextNode( + ".bztw_history { border: none; font-weight: normal; width: 58em; margin-left: 5em; }" + + ".bztw_inlinehistory { font-weight: normal; width: 56em; }" + + ".bztw_history .old, .bztw_inlinehistory .old { text-decoration: line-through; }" + + ".bztw_history .sep:before { content: \" \"; }" + + ".bztw_unconfirmed { font-style: italic; }" + + "tr.bz_tr_obsolete.bztw_plusflag { display: table-row !important; }" + + '.bztw_historyitem + .bztw_historyitem:before { content: "; "; }' + )); + d.getElementsByTagName("head")[0].appendChild(style); + style = d.createElement("style"); + style.setAttribute("type", "text/css"); + style.id = "bztw_cc"; + style.appendChild(d.createTextNode( + ".bztw_cc { display: none; }" + + '.bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: ""; }' + + '.bztw_historyitem:not([class~="bztw_cc"]) ~ .bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: "; "; }' + )); + d.getElementsByTagName("head")[0].appendChild(style); + + var userNameCache = {}; + function getUserName(email) { + if (email in userNameCache) { + return userNameCache[email]; + } + var emailLink = d.querySelectorAll("a.email"); + for (var i = 0; i < emailLink.length; ++i) { + if (emailLink[i].href == "mailto:" + email) { + return userNameCache[email] = htmlEncode(trimContent(emailLink[i])); + } + } + return email; + } + + // collect the flag names + var flagNames = [], flags = {}, flagOccurrences = {}; + var flagRows = d.querySelectorAll("#flags tr"); + for (var i = 0; i < flagRows.length; ++i) { + var item = flagRows[i].querySelectorAll("td"); + if (!item[1]) + continue; + var name = trimContent(item[1]).replace('\u2011', '-', 'g'); + flagNames.push(name); + flags[name] = item[1]; + } + flagRows = d.querySelectorAll(".field_label[id^=field_label_cf_]"); + for (var i = 0; i < flagRows.length; ++i) { + var name = trimContent(flagRows[i]).replace(/\:$/, '') + .replace('\u2011', '-', 'g'); + flagNames.push(name); + flags[name] = flagRows[i]; + } + var flagCounter = 1; + function findFlag(item) { + function lookup(names) { + names = names.split(", "); + var results = []; + for (var j = 0; j < names.length; ++j) { + var name = names[j].replace('\u2011', '-', 'g'); + for (var i = 0; i < flagNames.length; ++i) { + var quotedFlagName = flagNames[i].replace('.', '\\.', 'g') + .replace('\u2011', '-', 'g'); + if ((new RegExp('^' + quotedFlagName)).test(name)) { + results.push(flagNames[i]); + break; + } + } + } + return results; + } + var base = item[4] ? 2 : 0; + // handle normal flags + if (trimContent(item[base]) == 'Flags') { + var result = lookup(trimContent(item[base + 1])). + concat(lookup(trimContent(item[base + 2]))); + return result; + } + // handle special pseudo-flags + return lookup(trimContent(item[base])); + } + + var DataStore = new DataStoreCtor(d); + + var AttachmentFlagHandler = new AttachmentFlagHandlerCtor(); + AttachmentFlagHandler.determineInterestingFlags(d); + + var CheckinComment = new CheckinCommentCtor(); + CheckinComment.initialize(d, AttachmentFlagHandler._interestingFlags); + + var iframe = d.createElement('iframe'); + iframe.src = historyLink.href; + iframe.style.display = "none"; + iframe.addEventListener("load", function() { + preprocessDuplicateMarkers(d, iframe.contentDocument); + + var historyItems = iframe.contentDocument.querySelectorAll('#bugzilla-body tr'); + var commentTimes = d.querySelectorAll('.bz_comment_time'); + + // Sometimes the history will stack several changes together, + // and we'll want to append the data from the Nth item to the + // div created in N-1 + var i=0, j=0, flagsFound; + for (; i < historyItems.length; i++) { + var item = historyItems[i].querySelectorAll("td"); + if (!item[1]) + continue; + + var reachedEnd = false; + for (; j < commentTimes.length; j++) { + if (trimContent(item[1]) > trimContent(commentTimes[j])) { + if (j < commentTimes.length - 1) { + continue; + } else { + reachedEnd = true; + } + } + + var commentHead = commentTimes[j].parentNode; + + var mainUser = commentHead.querySelector(".bz_comment_user a.email") + .href + .substr(7); + var user = trimContent(item[0]); + var mainTime = trimContent(commentTimes[j]); + var time = trimContent(item[1]); + var inline = (mainUser == user && time == mainTime); + + var currentDiv = d.createElement("div"); + var userPrefix = ''; + if (inline) { + // assume that the change was made by the same user + commentHead.appendChild(currentDiv); + currentDiv.setAttribute("class", "bztw_inlinehistory"); + } else { + // the change was made by another user + if (!reachedEnd) { + var parentDiv = commentHead.parentNode; + if (parentDiv.previousElementSibling && + parentDiv.previousElementSibling.className.indexOf("bztw_history") >= 0) { + currentDiv = parentDiv.previousElementSibling; + } else { + parentDiv.parentNode.insertBefore(currentDiv, parentDiv); + } + } else { + var parentDiv = commentHead.parentNode; + if (parentDiv.nextElementSibling && + parentDiv.nextElementSibling.className.indexOf("bztw_history") >= 0) { + currentDiv = parentDiv.nextElementSibling; + } else { + parentDiv.parentNode.appendChild(currentDiv); + } + } + currentDiv.setAttribute("class", "bz_comment bztw_history"); + userPrefix += "" + + getUserName(trimContent(item[0])) + ": "; + } + // check to see if this is a flag setting + flagsFound = findFlag(item); + for (var idx = 0; idx < flagsFound.length; ++idx) { + var flag = flagsFound[idx]; + flagOccurrences[flag] = 'flag' + flagCounter; + if (inline) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", "flag" + flagCounter); + commentHead.insertBefore(anchor, commentHead.firstChild); + } else { + userPrefix += ''; + } + ++flagCounter; + } + + var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); + if (inline) { + for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", attachmentFlagAnchors[idx]); + commentHead.insertBefore(anchor, commentHead.firstChild); + } + } else { + userPrefix += attachmentFlagAnchors.map(function(name) '').join(""); + } + + var ccOnly = (trimContent(item[2]) == 'CC'); + var ccPrefix = ccOnly ? '' : + '', + ccSuffix = ''; + var html = userPrefix + + ccPrefix + + transformType(trimContent(item[2]), d, trimContent(item[3]), + trimContent(item[4])) + ": " + + formatTransition(trimContent(item[3]), trimContent(item[4]), + trimContent(item[2]), d, iframe.contentDocument); + + var nextItemsCount = item[0].rowSpan; + for (var k = 1; k < nextItemsCount; ++k) { + ccOnly = false; + item = historyItems[++i].querySelectorAll("td") + ccPrefix = (trimContent(item[0]) == 'CC') ? + '' : ''; + // avoid showing a trailing semicolon if the previous entry wasn't a CC and this one is + var prefix = ccSuffix + ccPrefix; + // check to see if this is a flag setting + flagsFound = findFlag(item); + for (var idx = 0; idx < flagsFound.length; ++idx) { + var flag = flagsFound[idx]; + flagOccurrences[flag] = 'flag' + flagCounter; + if (inline) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", "flag" + flagCounter); + commentHead.insertBefore(anchor, commentHead.firstChild); + } else { + prefix += ''; + } + ++flagCounter; + } + + var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); + if (inline) { + for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", attachmentFlagAnchors[idx]); + commentHead.insertBefore(anchor, commentHead.firstChild); + } + } else { + prefix += attachmentFlagAnchors.map(function(name) '').join(""); + } + + html += prefix + + transformType(trimContent(item[0]), d, trimContent(item[1]), + trimContent(item[2])) + ": " + + formatTransition(trimContent(item[1]), trimContent(item[2]), + trimContent(item[0]), d, iframe.contentDocument); + } + html += ccSuffix; + if (ccOnly) { + html = '
' + html + '
'; + } else { + html = '
' + html + '
'; + } + currentDiv.innerHTML += html; + break; + } + } + + handleEmptyCollapsedBoxes(d); + + // Set the latest flag links if necessary + for (var flagName in flagOccurrences) { + flags[flagName].innerHTML = '' + + flags[flagName].innerHTML + ''; + } + + AttachmentFlagHandler.setupLinks(d); + },true); + d.body.appendChild(iframe); + + tbplbotSpamCollapser(d); +} + +var TransformValues = { + linkifyURLs: function (str) { + return str.replace(/((https?|ftp)\:\/\/[\S]+)/g, '$1'); + }, + linkifyBugAndCommentNumbers: function (str) { + return str.replace(/(bug )(\d+) (comment )(\d+)/gi, '$1\n$2 $3\n$4'); + }, + linkifyCommentNumbers: function (str) { + return str.replace(/(comment (\d+))/gi, '$1'); + }, + linkifyBugNumbers: function (str) { + return str.replace(/(bug (\d+))/gi, '$1'); + }, + linkifyDependencies: function (str, type, doc, histDoc) { + switch (type) { + case "Blocks": + case "Depends on": + case "Duplicate": + str = str.replace(/\d+/g, function(str) { + var link = histDoc.querySelector("a[href='show_bug.cgi?id=" + str + "']"); + if (link) { + var class_ = ''; + if (/bz_closed/i.test(link.className)) { + class_ += 'bz_closed '; + } else if (/bztw_unconfirmed/i.test(link.className)) { + class_ += 'bztw_unconfirmed '; + } + var parent = link.parentNode; + if (parent) { + if (parent.tagName.toLowerCase() == "i") { + class_ += 'bztw_unconfirmed '; + } + if (/bz_closed/i.test(parent.className)) { + class_ += 'bz_closed '; + } + } + str = applyClass(class_, + '' + htmlEncode(str) + ''); + } + return str; + }); + } + return str; + } +}; + +function transform(str, type, doc, histDoc) { + for (var funcname in TransformValues) { + var func = TransformValues[funcname]; + str = func.call(null, str, type, doc, histDoc); + } + return str +} + +var TransformTypes = { + linkifyAttachments: function (str, doc) { + return str.replace(/(Attachment #(\d+))/g, function (str, x, id) { + var link = doc.querySelector("a[href='attachment.cgi?id=" + id + "']"); + if (link) { + var class_ = ''; + if (/bz_obsolete/i.test(link.className)) { + class_ += 'bz_obsolete '; + } + var parent = link.parentNode; + if (parent && /bz_obsolete/i.test(parent.className)) { + class_ += 'bz_obsolete '; + } + if (link.querySelector(".bz_obsolete")) { + class_ += 'bz_obsolete '; + } + str = applyClass(class_, + '' + htmlEncode(str) + ''); + } + return str; + }); + }, + changeDependencyLinkTitles: function (str, doc, old, new_) { + switch (str) { + case "Blocks": + case "Depends on": + if (old.length && !new_.length) { // if the dependency was removed + str = "No longer " + str[0].toLowerCase() + str.substr(1); + } + break; + } + return str; + } +}; + +function transformType(str, doc, old, new_) { + for (var funcname in TransformTypes) { + var func = TransformTypes[funcname]; + str = func.call(null, str, doc, old, new_); + } + return str; +} + +// new is a keyword, which makes this function uglier than I'd like +function formatTransition(old, new_, type, doc, histDoc) { + if (old.length) { + old = transform(htmlEncode(old), type, doc, histDoc); + var setOldStyle = true; + switch (type) { + case "Blocks": + case "Depends on": + setOldStyle = false; + break; + } + if (setOldStyle) { + old = '' + old + ''; + } + } + if (new_.length) { + new_ = '' + transform(htmlEncode(new_), type, doc, histDoc) + ''; + } + var mid = ''; + if (old.length && new_.length) { + mid = ' '; + } + return old + mid + new_; +} + +function trimContent(el) { + return el.textContent.trim(); +} + +function AttachmentFlag(flag) { + for (var name in flag) + this[name] = flag[name]; +} +AttachmentFlag.prototype = { + equals: function(flag) { + if (this.type != flag.type || + this.name != flag.name || + this.setter != flag.setter || + ("requestee" in this && !("requestee" in flag)) || + ("requestee" in flag && !("requestee" in this))) + return false; + return this.requestee == flag.requestee; + } +}; + +var reAttachmentDiff = /attachment\.cgi\?id=(\d+)&action=diff$/i; +var reviewBoardUrlBase = "http://reviews.visophyte.org/"; + +/** + * Whenever we find a patch with a diff, insert an additional link to asuth's + * review board magic. + */ +function attachmentDiffLinkify(doc) { + var bug_id = getBugNumber(doc); + + var table = doc.getElementById("attachment_table"); + if (!table) + return; + var rows = table.querySelectorAll("tr"); + for (var i = 0; i < rows.length; ++i) { + var item = rows[i].querySelectorAll("td"); + if (item.length != 3) + continue; + // get the ID of the attachment + var links = item[2].querySelectorAll("a"); + if (links.length != 2) + continue; + var match = reAttachmentDiff.exec(links[1].href); + if (match) { + var attach_id = match[1]; + var parentNode = links[1].parentNode; + parentNode.appendChild(doc.createTextNode(" | ")); + var linkNode = doc.createElement("a"); + linkNode.href = reviewBoardUrlBase + "r/bzpatch/bug" + bug_id + "/attach" + attach_id + "/"; + linkNode.textContent = "Review"; + parentNode.appendChild(linkNode); + } + } +} + +function quicksearchHandler(doc) { + var win = doc.defaultView; + var match = /quicksearch=([^&]+)/i.exec(win.location.search); + if (match) { + var quicksearch = unescape(match[1].replace('+', ' ', 'g')); + var quicksearchBox = doc.querySelectorAll("input[name=quicksearch]"); + if (quicksearchBox) { + for (var i = 0; i < quicksearchBox.length; ++i) { + quicksearchBox[i].value = quicksearch; + } + } + } +} + +function AttachmentFlagHandlerCtor() { + this._db = {}; + this._interestingFlags = {}; +} +AttachmentFlagHandlerCtor.prototype = { + determineInterestingFlags: function (doc) { + var table = doc.getElementById("attachment_table"); + if (!table) + return; + var rows = table.querySelectorAll("tr"); + for (var i = 0; i < rows.length; ++i) { + var item = rows[i].querySelectorAll("td"); + if (item.length != 3 || + item[1].className.indexOf("bz_attach_flags") < 0 || + trimContent(item[1]) == "no flags") + continue; + // get the ID of the attachment + var link = item[0].querySelector("a"); + if (!link) + continue; + var match = this._reAttachmentHref.exec(link.href); + if (match) { + var attachmentID = match[1]; + if (!(attachmentID in this._interestingFlags)) { + this._interestingFlags[attachmentID] = []; + } + var text = ""; + var previousText = ""; + var previousEl = null; + for (var el = item[1].firstChild; el.nextSibling; el = el.nextSibling) { + var thisText = trimContent(el).replace('\u2011', '-', 'g'); + text += thisText; + if (this._reParsePartToLinkify.test(thisText)) { + previousText = thisText; + previousEl = el; + } + if (el.nodeType != el.ELEMENT_NODE || + el.localName.toLowerCase() != "br") + continue; + match = this._reParseInterestingFlag.exec(text); + if (match) { + var flag = {}; + flag.setter = match[1]; + flag.name = match[2]; + if (match[4] == "+" || match[4] == "-") { + flag.type = match[4]; + } else { + flag.type = "?"; + if (match[7]) { + flag.requestee = match[7]; + } + } + + // always show the obsolete attachments with a + flag + if (flag.type == "+") { + var parent = link.parentNode; + while (parent) { + if (parent.tagName.toLowerCase() == "tr") { + if (/bz_tr_obsolete/i.test(parent.className)) { + parent.className += " bztw_plusflag"; + } + break; + } + parent = parent.parentNode; + } + } + + // try to put the flag name and type part in a span which we will + // use in setupLinks to inject links into. + match = this._reLinkifyInterestingFlag.exec(previousText); + if (match) { + previousEl.textContent = match[1]; + if (match[3]) { + var textNode = doc.createTextNode(match[3]); + previousEl.parentNode.insertBefore(textNode, previousEl.nextSibling); + } + var span = doc.createElement("span"); + span.textContent = match[2]; + previousEl.parentNode.insertBefore(span, previousEl.nextSibling); + + flag.placeholder = span; + } + + this._interestingFlags[attachmentID].push(new AttachmentFlag(flag)); + } + text = ""; + previousText = ""; + previousEl = null; + } + } + } + }, + handleItem: function (name, item) { + var anchorsCreated = []; + var base = item[4] ? 2 : 0; + var what = trimContent(item[base]); + var match = this._reAttachmentFlagName.exec(what); + if (match) { + var id = match[1]; + if (!(id in this._db)) { + this._db[id] = []; + } + name = name.split('@')[0]; // convert the name to the fraction before the @ + var added = this._parseData(name, trimContent(item[base + 2])); + for (var i = 0; i < added.length; ++i) { + var flag = added[i]; + if (!(id in this._interestingFlags)) + continue; + for (var j = 0; j < this._interestingFlags[id].length; ++j) { + // Take care to not assign an anchor to a flag which already has one + if (flag.equals(this._interestingFlags[id][j]) && + !("anchor" in this._interestingFlags[id][j])) { + // found an interesting flag + this._interestingFlags[id][j].anchor = this.anchorName; + anchorsCreated.push(this.anchorName); + this._counter++; + break; + } + } + } + } + return anchorsCreated; + }, + setupLinks: function (doc) { + for (var id in this._interestingFlags) { + for (var i = 0; i < this._interestingFlags[id].length; ++i) { + var flag = this._interestingFlags[id][i]; + if ("placeholder" in flag && + "anchor" in flag) { + var link = doc.createElement("a"); + link.href = "#" + flag.anchor; + link.textContent = flag.placeholder.textContent; + flag.placeholder.replaceChild(link, flag.placeholder.firstChild); + } + } + } + }, + _parseData: function (name, str) { + var items = str.replace('\u2011', '-', 'g').split(', '), flags = []; + for (var i = 0; i < items.length; ++i) { + if (!items[i].length) + continue; + + var match = this._reParseRequest.exec(items[i]); + if (match) { + var flag = {}; + flag.name = match[1]; + flag.setter = name; + if (match[4]) { + flag.requestee = match[4]; + } + flag.type = match[2]; + flags.push(new AttachmentFlag(flag)); + } + } + return flags; + }, + _counter: 1, + get anchorName() { + return "attachflag" + this._counter; + }, + _reParseRequest: /^(.+)([\?\-\+])(\((.+)@.+\))?$/, + _reParsePartToLinkify: /^\s*:\s+.+[\-\+\?](\s*\()?\s*$/, + _reParseInterestingFlag: /^(.+):\s+(.+)(([\-\+])|\?(\s+(\((.+)\)))?)$/, + _reLinkifyInterestingFlag: /^(\s*:\s+)(.+[\-\+\?])(\s*\(\s*)?$/, + _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i, + _reAttachmentFlagName: /^Attachment\s+#(\d+)\s+Flags$/i +}; + +function CheckinCommentCtor() { + this.bugNumber = null; + this.summarySpan = null; + this.checkinFlags = ""; +} +CheckinCommentCtor.prototype = { + initialize: function(doc, flags) { + this.bugNumber = getBugNumber(doc); + var summarySpan = doc.getElementById("short_desc_nonedit_display"); + if (summarySpan) { + this.summary = summarySpan.textContent; + } + var checkinFlagsMap = {}; + for (var id in flags) { + for (var i = 0; i < flags[id].length; ++i) { + var flag = flags[id][i]; + if (flag.type == "+") { + var name = flag.name; + if (name == "review") { + name = "r"; + } else if (name == "superreview") { + name = "sr"; + } else if (name == "ui-review") { + name = "ui-r"; + } else if (name == "feedback") { + name = "f"; + } + if (!(name in checkinFlagsMap)) { + checkinFlagsMap[name] = {}; + } + checkinFlagsMap[name][flag.setter]++; + } + } + } + var flagsOrdered = []; + for (var name in checkinFlagsMap) { + flagsOrdered.push(name); + } + flagsOrdered.sort(function (a, b) { + function convertToNumber(x) { + switch (x) { + case "f": + return -4; + case "r": + return -3; + case "sr": + return -2; + case "ui-r": + return -1; + default: + return 0; + } + } + var an = convertToNumber(a); + var bn = convertToNumber(b); + if (an == 0 && bn == 0) { + return a < b ? -1 : (a = b ? 0 : 1); + } else { + return an - bn; + } + }); + var checkinFlags = []; + for (var i = 0; i < flagsOrdered.length; ++i) { + var name = flagsOrdered[i]; + var flag = name + "="; + var setters = []; + for (var setter in checkinFlagsMap[name]) { + setters.push(setter); + } + flag += setters.join(","); + checkinFlags.push(flag); + } + this.checkinFlags = checkinFlags.join(" "); + if (this.isValid()) { + var div = doc.createElement("div"); + div.setAttribute("style", "display: none;"); + div.id = "__bz_tw_checkin_comment"; + div.appendChild(doc.createTextNode(this.toString())); + doc.body.appendChild(div); + } + }, + isValid: function() { + return this.bugNumber != null && + this.summary != null; + }, + toString: function() { + if (!this.isValid()) { + return ""; + } + var message = "Bug " + this.bugNumber + " - " + this.summary; + if (this.checkinFlags.length) { + message += "; " + this.checkinFlags; + } + return message; + } +}; + +function DataStoreCtor(doc) { + this.storage = doc.defaultView.localStorage; + this.data = {}; + this.bugNumber = null; + function visualizeStoredData() { + var data = ""; + for (var i = 0; i < window.localStorage.length; ++i) { + var key = window.localStorage.key(i); + data += key + ": " + JSON.parse(window.localStorage.getItem(key).toString()).toSource() + "\n"; + } + open("data:text/html,
" + escape(htmlEncode(data)) + "
"); + } + function clearStoredData() { + var count = window.localStorage.length; + if (count > 0) { + if (window.confirm("You currently have data stored for " + count + " bugs.\n\n" + + "Are you sure you want to clear this data? This action cannot be undone.")) { + window.localStorage.clear(); + } + } else { + alert("You don't have any data stored about your bugs"); + } + } + var script = doc.createElement("script"); + script.appendChild(doc.createTextNode(visualizeStoredData.toSource() + + clearStoredData.toSource() + + htmlEncode.toSource())); + doc.body.appendChild(script); + this.initialize(doc); +} + +DataStoreCtor.prototype = { + initialize: function(doc) { + this.bugNumber = getBugNumber(doc); + var data = this._ensureEntry(this.bugNumber, this.data); + // last visited date + data.visitedTime = (new Date()).getTime(); + // last comment count + data.commentCount = doc.querySelectorAll(".bz_comment").length; + // last status of bug flags + var flags = this._ensureEntry("flags", data); + var flagRows = doc.querySelectorAll("#flags tr"); + for (var i = 0; i < flagRows.length; ++i) { + var flagCols = flagRows[i].querySelectorAll("td"); + if (flagCols.length != 3) { + continue; + } + var flagName = trimContent(flagCols[1]); + var flagValue = flagCols[2].querySelector("select"); + if (flagValue) { + flagValue = flagValue.value; + } else { + continue; + } + flags[flagName] = flagValue; + } + flagRows = doc.querySelectorAll(".field_label[id^=field_label_cf_]"); + for (var i = 0; i < flagRows.length; ++i) { + var flagName = trimContent(flagRows[i]).replace(/:$/, ""); + var flagValue = flagRows[i].parentNode.querySelector("select"); + if (flagValue) { + flagValue = flagValue.value; + } else { + continue; + } + flags[flagName] = flagValue; + } + // last attachments + var attachmentTable = doc.getElementById("attachment_table"); + var attachmentRows = attachmentTable.querySelectorAll("tr"); + for (var i = 0; i < attachmentRows.length; ++i) { + var attachmentCells = attachmentRows[i].querySelectorAll("td"); + if (attachmentCells.length != 3) { + continue; + } + var link = attachmentCells[0].querySelector("a"); + var match = this._reAttachmentHref.exec(link.href); + if (match) { + var attachmentID = match[1]; + var attachment = this._ensureEntry("attachments", data); + var attachmentFlags = this._ensureArray(attachmentID, attachment); + for (var el = attachmentCells[1].firstChild; el.nextSibling; el = el.nextSibling) { + if (el.nodeType != el.TEXT_NODE) { + continue; + } + var text = trimContent(el); + if (!text) { + continue; + } + match = this._reParseInterestingFlag.exec(text); + if (match) { + var flag = {}; + flag.setter = match[1]; + flag.name = match[2]; + if (match[4] == "+" || match[4] == "-") { + flag.type = match[4]; + } else { + flag.type = "?"; + if (match[7]) { + flag.requestee = match[7]; + } + } + attachmentFlags.push(flag); + } + } + } + } + // Write data to storage + for (var key in this.data) { + this._ensure(key, this.storage, JSON.stringify(this.data[key])); + } + }, + _ensure: function(entry, obj, val) { + if (obj.toString().indexOf("[object Storage") >= 0) { + obj.setItem(entry, val); + } else { + if (typeof obj[entry] == "undefined") + obj[entry] = val; + return obj[entry]; + } + }, + _ensureEntry: function(entry, obj) { + return this._ensure(entry, obj, {}); + }, + _ensureArray: function(entry, obj) { + return this._ensure(entry, obj, []); + }, + _reParseInterestingFlag: /^(.+):\s+(.+)(([\-\+])|\?(\s+(\((.+)\)))?)$/, + _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i +}; + +function getBugNumber(doc) { + var idField = doc.querySelector("form[name=changeform] input[name=id]"); + if (idField) { + return idField.value; + } + return null; +} + +function getUserName(doc) { + var links = doc.querySelectorAll("#header .links li"); + var last = links[links.length - 1]; + if (last.innerHTML.indexOf("logout") >= 0) { + return trimContent(last.lastChild); + } + return null; +} + +function handleEmptyCollapsedBoxes(doc) { + // first, try to get the display style of a CC field (any would do) + var historyBoxes = doc.querySelectorAll(".bztw_history"); + for (var i = 0; i < historyBoxes.length; ++i) { + var box = historyBoxes[i]; + for (var j = 0; j < box.childNodes.length; ++j) { + var child = box.childNodes[j], found = true; + if (child.nodeType != child.ELEMENT_NODE) + continue; + if (child.className == "sep") { + // separators are insignificant + continue; + } else if (!/bztw_cc/.test(child.className)) { + found = false; + break; + } + } + if (found) { + box.className += " bztw_cc"; + } + } +} + +function applyClass(class_, html) { + return '' + html + ''; +} + +function htmlEncode(str) { + return str.replace('&', '&', 'g') + .replace('<', '<', 'g') + .replace('>', '>', 'g') + .replace('"', '"', 'g'); +} + +function tbplbotSpamCollapser(d) { + var collapseExpandBox = d.querySelector(".bz_collapse_expand_comments"); + if (!collapseExpandBox) { + return; + } + var a = d.createElement("a"); + a.href = "#"; + a.addEventListener("click", function(e) { + e.preventDefault(); + var win = d.defaultView; + var comments = d.querySelectorAll(".bz_comment"); + for (var i = 0; i < comments.length; ++i) { + var comment = comments[i]; + try { + if (comment.querySelector(".bz_comment_user a.email").href.substr(7) == + "tbplbot@gmail.com") { + win.collapse_comment(comment.querySelector(".bz_collapse_comment"), + comment.querySelector(".bz_comment_text")); + } + } catch (e) { + continue; + } + } + return false; + }, false); + a.appendChild(d.createTextNode("Collapse All tbplbot Comments")); + var li = d.createElement("li"); + li.appendChild(a); + collapseExpandBox.appendChild(li); +} + +tweakBugzilla(document); diff --git a/data/lib/cc-context.js b/data/lib/cc-context.js new file mode 100644 index 0000000..38397a9 --- /dev/null +++ b/data/lib/cc-context.js @@ -0,0 +1,8 @@ +on('click', function(node, data) { + var style = document.getElementById("bztw_cc"); + style.disabled = !style.disabled; +}); + +on('context', function(node) { + return onBugzillaPage(document.URL); +}); diff --git a/data/lib/checkin-context.js b/data/lib/checkin-context.js new file mode 100644 index 0000000..4d073be --- /dev/null +++ b/data/lib/checkin-context.js @@ -0,0 +1,11 @@ +on('click', function(node, data) { + var message = document.getElementById("__bz_tw_checkin_comment"); + postMessage(message.textContent); +}); + +on('context', function(node) { + if (!onBugzillaPage(document.URL)) + return false; + var message = document.getElementById("__bz_tw_checkin_comment"); + return !!message; +}); diff --git a/data/lib/preprocessDuplicates.js b/data/lib/preprocessDuplicates.js new file mode 100644 index 0000000..44ea5ca --- /dev/null +++ b/data/lib/preprocessDuplicates.js @@ -0,0 +1,120 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Bugzilla Tweaks. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johnathan Nightingale + * Ehsan Akhgari + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +function preprocessDuplicateMarkers(mainDoc, histDoc) { + var comments = mainDoc.querySelectorAll(".bz_comment"); + var reDuplicate = /^\s*\*\*\*\s+Bug\s+(\d+)\s+has\s+been\s+marked\s+as\s+a\s+duplicate\s+of\s+this\s+bug.\s+\*\*\*\s*$/i; + var row = 0; + var rows = histDoc.querySelectorAll("#bugzilla-body tr"); + for (var i = 1 /* comment 0 can never be a duplicate marker */; + i < comments.length; ++i) { + var textHolder = comments[i].querySelector(".bz_comment_text"); + var match = reDuplicate.exec(trimContent(textHolder)); + if (match) { + // construct the table row to be injected in histDoc + var bugID = match[1]; + var email = comments[i].querySelector(".bz_comment_user .email") + .href + .substr(7); + var link = textHolder.querySelector("a"); + var title = link.title; + var time = trimContent(comments[i].querySelector(".bz_comment_time")); + var what = 'Duplicate'; + var removed = ''; + var number = trimContent(comments[i].querySelector(".bz_comment_number")). + replace(/[^\d]+/g, ''); + var class_ = ''; + if (/bz_closed/i.test(link.className + " " + link.parentNode.className)) { + class_ += 'bz_closed '; + } + if (link.parentNode.tagName.toLowerCase() == 'i') { + class_ += 'bztw_unconfirmed '; + } + var added = '' + bugID + ''; + + // inject the table row + var reachedEnd = false; + for (; row < rows.length; ++row) { + var cells = rows[row].querySelectorAll("td"); + if (cells.length != 5) + continue; + if (time > trimContent(cells[1])) { + if (row < rows.length - 1) { + continue; + } else { + reachedEnd = true; + } + } + if (time == trimContent(cells[1])) { + cells[0].rowSpan++; + cells[1].rowSpan++; + var rowContents = [what, removed, added]; + var tr = histDoc.createElement("tr"); + rowContents.forEach(function (cellContents) { + var td = histDoc.createElement("td"); + td.innerHTML = cellContents; + tr.appendChild(td); + }); + if (row != rows.length - 1) { + rows[row].parentNode.insertBefore(tr, rows[row+1]); + } else { + rows[row].parentNode.appendChild(tr); + } + } else { + var rowContents = [email, time, what, removed, added]; + var tr = histDoc.createElement("tr"); + rowContents.forEach(function (cellContents) { + var td = histDoc.createElement("td"); + td.innerHTML = cellContents; + tr.appendChild(td); + }); + if (reachedEnd) { + rows[row].parentNode.appendChild(tr); + } else { + rows[row].parentNode.insertBefore(tr, rows[row]); + } + } + break; + } + + // remove the comment from the main doc + comments[i].parentNode.removeChild(comments[i]); + } + } +} diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index 9af0127..f57af79 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -240,7 +240,7 @@ function pasteBacktraceInComments(atts) { createDeadLink ("callAbrtQuery_link", "Abrt bugs", mainTitle, abrtQueryURL, [], false, null, "a"); - + if (idContainsWord("cf_devel_whiteboard", 'btparsed')) { addStuffToTextBox('status_whiteboard', 'btparsed'); } diff --git a/data/lib/urltest.js b/data/lib/urltest.js new file mode 100644 index 0000000..a0dbabf --- /dev/null +++ b/data/lib/urltest.js @@ -0,0 +1,4 @@ +function onBugzillaPage(url) { + return /https:\/\/bugzilla(-[a-zA-Z]+)*\.mozilla\.org/.test(url) + || /https:\/\/landfill.*\.bugzilla\.org/.test(url); +} \ No newline at end of file diff --git a/data/lib/util.js b/data/lib/util.js index f336a7f..6cbb493 100644 --- a/data/lib/util.js +++ b/data/lib/util.js @@ -124,14 +124,18 @@ function createDeadLink (id, text, parent, callback, params, before, covered, ac }, false); } + locParent.appendChild(newAElem); + if ((before === "br") || (before === true)) { locParent.appendChild(document.createElement("br")); } else if (before === "dash") { locParent.appendChild(document.createTextNode("\u00A0-\u00A0")); } - - locParent.appendChild(newAElem); + else if (before === "parens") { + locParent.appendChild(document.createTextNode(")")); + locParent.insertBefore(document.createTextNode("("), newAElem); + } } /* diff --git a/data/lib/viewSource.js b/data/lib/viewSource.js new file mode 100644 index 0000000..25cba58 --- /dev/null +++ b/data/lib/viewSource.js @@ -0,0 +1,100 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Bugzilla Tweaks. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johnathan Nightingale + * Ehsan Akhgari + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var reAttachmentType = /,\s+([^ )]*)[;)]/; + +function viewAttachmentSource(doc) { + function addLink(elem, title, href) { + if (elem.textContent.match(/[\S]/)) { + elem.appendChild(doc.createTextNode(" | ")); + } + var link = doc.createElement("a"); + link.href = href; + link.textContent = title; + elem.appendChild(link); + } + var table = doc.getElementById("attachment_table"); + if (!table) + return; + var rows = table.querySelectorAll("tr"); + for (var i = 0; i < rows.length; ++i) { + var items = rows[i].querySelectorAll("td"); + if (items.length != 3) + continue; + var links = items[0].querySelectorAll("a"); + if (links.length == 0) + continue; + var attachHref = links[0].href; + // get the type of the attachment + var span = items[0].querySelector(".bz_attach_extra_info"); + if (!span) + continue; + var typeName = null; + try { + // Match mime type followed by ";" (charset) or ")" (no charset) + typeName = span.textContent.match(reAttachmentType)[1]; + typeName = typeName.split(";")[0]; // ignore charset following type + } catch (e) {} + if (typeName == "application/java-archive" || + typeName == "application/x-jar") { + // Due to the fix for bug 369814, only zip files with this special + // mime type can be used with the jar: protocol. + // http://hg.mozilla.org/mozilla-central/rev/be54f6bb9e1e + addLink(items[2], "JAR Contents", "jar:" + attachHref + "!/"); + // https://bugzilla.mozilla.org/show_bug.cgi?id=369814#c5 has more possible mime types for zips? + } else if (typeName == "application/zip" || + typeName == "application/x-zip-compressed" || + typeName == "application/x-xpinstall") { + addLink(items[2], "Static ZIP Contents", "jar:" + attachHref + "!/"); + } else if (typeName != "text/plain" && + typeName != "patch" && + // Other types that Gecko displays like text/plain + // http://mxr.mozilla.org/mozilla-central/source/parser/htmlparser/public/nsIParser.h + typeName != "text/css" && + typeName != "text/javascript" && + typeName != "text/ecmascript" && + typeName != "application/javascript" && + typeName != "application/ecmascript" && + typeName != "application/x-javascript" && + // Binary image types for which the "source" is not useful + typeName != "image/gif" && + typeName != "image/png" && + typeName != "image/jpeg") { + addLink(items[2], "Source", "view-source:" + attachHref); + } + } +} diff --git a/lib/libbugzilla.js b/lib/libbugzilla.js index 45a1fc4..613dbb3 100644 --- a/lib/libbugzilla.js +++ b/lib/libbugzilla.js @@ -170,7 +170,7 @@ exports.getInstalledPackages = function getInstalledPackages(locationLoginObj, c var allIdx = null; if ((allIdx = enabledPackages.indexOf("all")) != -1) { enabledPackages = enabledPackages.splice(allIdx, - config.gJSONData.commentPackages.keys()); + Object.keys(config.gJSONData.commentPackages)); } // TODO To be decided, whether we cannot just eliminate packages in diff --git a/lib/logger.js b/lib/logger.js index 4411a72..19fabb5 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -1,5 +1,4 @@ -/ -Released under the MIT/X11 license +// Released under the MIT/X11 license // http://www.opensource.org/licenses/mit-license.php "use strict"; var urlMod = require("url"); diff --git a/lib/main.js b/lib/main.js index 3e128ac..62c064a 100644 --- a/lib/main.js +++ b/lib/main.js @@ -1,4 +1,3 @@ -<<<<<<< HEAD // Released under the MIT/X11 license // http://www.opensource.org/licenses/mit-license.php // @@ -114,12 +113,15 @@ var messageHandler = exports.messageHandler = function messageHandler(worker, ms }; var contentScriptLibraries = [ - self.data.url('js/urltest.js'), - self.data.url('js/bug-page-mod.js'), + self.data.url('lib/urltest.js'), self.data.url("lib/jumpNextBug.js"), self.data.url("lib/util.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/logging-front.js"), + self.data.url('lib/bug-page-mod.js'), self.data.url("lib/rhbzpage.js"), self.data.url("lib/bzpage.js") ]; @@ -161,14 +163,14 @@ pageMod.PageMod({ // Allow toggling of CC event displays using a context menu entry contextMenu.Item({ label: "Toggle CC History", - contentScriptFile: [self.data.url('js/urltest.js'), - self.data.url('js/cc-context.js')] + contentScriptFile: [self.data.url('lib/urltest.js'), + self.data.url('lib/cc-context.js')] }); contextMenu.Item({ label: "Copy Check-in Comment", - contentScriptFile: [self.data.url('js/urltest.js'), - self.data.url('js/checkin-context.js')], + contentScriptFile: [self.data.url('lib/urltest.js'), + self.data.url('lib/checkin-context.js')], onMessage: function (comment) { require("clipboard").set(comment); } diff --git a/package.json b/package.json index 78f985b..1fbb0f3 100644 --- a/package.json +++ b/package.json @@ -7,15 +7,12 @@ "description": "Additional buttons and other function helping in the triage on bugzilla", "author": "Matej Cepl (http://matej.ceplovi.cz)", "license": "MIT/X11 (http://opensource.org/licenses/mit-license.php) and MPL", - "version": "0.92" + "version": "0.92", "contributors": [ "Ehsan Akhgari (http://ehsanakhgari.org/) ", "Johnathan Nightingale (http://johnath.com) ", "Heather Arthur (http://harthur.wordpress.com/) ", "Steve Fink (http://blog.mozilla.com/sfink/) " ], - "url": "http://ehsanakhgari.org/mozilla/extensions/firefox/bugzilla-tweaks", - "version": "1.10", - "fullName": "Bugzilla Tweaks", - "id": "jid0-qBnIpLfDFa4LpdrjhAC6vBqN20Q" + "url": "https://fedorahosted.org/bugzilla-triage-scripts/" } -- cgit From 75815608b97febce430a5f85b7eb7ce737470a12 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 17 Mar 2011 00:40:09 +0100 Subject: First ideas about splitting queries to separate module. --- data/lib/bzpage.js | 67 -------------------------------------------------- data/lib/queries.js | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/main.js | 1 + 3 files changed, 71 insertions(+), 67 deletions(-) create mode 100644 data/lib/queries.js diff --git a/data/lib/bzpage.js b/data/lib/bzpage.js index 9afb112..d3250ba 100644 --- a/data/lib/bzpage.js +++ b/data/lib/bzpage.js @@ -713,73 +713,6 @@ function getLogin () { return loginStr; } -function getSelection () { - var text = ""; - var selectionObject = window.getSelection(); - if (selectionObject.rangeCount > 0) { - text = selectionObject.getRangeAt(0).toString().trim(); - } - return text; -} - -/** - * 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, if undefined, - * search in all products - * @return None - * - */ -function queryInNewTab(text, component, product) { - var urlStr = "https://" + window.location.hostname + "/buglist.cgi?query_format=advanced"; - if (product) { - urlStr += "&product=" + product.trim(); - } - if (component) { - if ("equivalentComponents" in constantData) { - var equivCompsArr = constantData.equivalentComponents. - filter(function (REstr) { - return new RegExp(REstr).test(getComponent()); - }, this); - if (equivCompsArr.length > 0) { - component = equivCompsArr[0]; - } - } - urlStr += "&component=" + component.trim(); - } - - // using more complicated query tables here, because they can be more easily - // edited - // for further investigative searches - if (text) { - text = encodeURIComponent(text.trim()); - var searchText = "&field0-0-0=longdesc&type0-0-0=substring&value0-0-0=" - + text - + "&field0-0-1=attach_data.thedata&type0-0-1=substring&value0-0-1=" - + text - + "&field0-0-2=status_whiteboard&type0-0-2=substring&value0-0-2=" - + text; - urlStr += searchText; - postMessage(new Message("OpenURLinTab", urlStr)); - } -} - -/** - * Get the text to search for and prepare other things for the real executive - * function this.queryInNewTab, and run it. - */ -function queryForSelection() { - var text = getSelection(); - if (!text) { - postMessage(new Message("GetClipboard", "queryLocal")); - } - else { - queryInNewTab(text, getComponent(), getProduct()); - } -} - /** * adds a person to the CC list, if it isn't already there * diff --git a/data/lib/queries.js b/data/lib/queries.js new file mode 100644 index 0000000..b43b616 --- /dev/null +++ b/data/lib/queries.js @@ -0,0 +1,70 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php +"use strict"; + +function getSelection () { + var text = ""; + var selectionObject = window.getSelection(); + if (selectionObject.rangeCount > 0) { + text = selectionObject.getRangeAt(0).toString().trim(); + } + return text; +} + + +/** + * 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, if undefined, + * search in all products + * @return None + * + */ +function queryInNewTab(text, component, product) { + var urlStr = "https://" + window.location.hostname + "/buglist.cgi?query_format=advanced"; + if (product) { + urlStr += "&product=" + product.trim(); + } + if (component) { + if ("equivalentComponents" in constantData) { + var equivCompsArr = constantData.equivalentComponents. + filter(function (REstr) { + return new RegExp(REstr).test(getComponent()); + }, this); + if (equivCompsArr.length > 0) { + component = equivCompsArr[0]; + } + } + urlStr += "&component=" + component.trim(); + } + + // using more complicated query tables here, because they can be more easily + // edited + // for further investigative searches + if (text) { + text = encodeURIComponent(text.trim()); + var searchText = "&field0-0-0=longdesc&type0-0-0=substring&value0-0-0=" + + text + + "&field0-0-1=attach_data.thedata&type0-0-1=substring&value0-0-1=" + + text + + "&field0-0-2=status_whiteboard&type0-0-2=substring&value0-0-2=" + + text; + urlStr += searchText; + postMessage(new Message("OpenURLinTab", urlStr)); + } +} + +/** + * Get the text to search for and prepare other things for the real executive + * function this.queryInNewTab, and run it. + */ +function queryForSelection() { + var text = getSelection(); + if (!text) { + postMessage(new Message("GetClipboard", "queryLocal")); + } else { + queryInNewTab(text, getComponent(), getProduct()); + } +} diff --git a/lib/main.js b/lib/main.js index 62c064a..72a5fe8 100644 --- a/lib/main.js +++ b/lib/main.js @@ -116,6 +116,7 @@ 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/preprocessDuplicates.js"), self.data.url("lib/viewSource.js"), self.data.url("lib/color.js"), -- cgit From 39e8a732fed33c134a301fad446b13223c4b3fc3 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Mon, 21 Mar 2011 00:32:05 +0100 Subject: CLeaned queries.js so that it is independent of external forces. --- data/lib/bzpage.js | 7 +++++-- data/lib/queries.js | 17 +++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/data/lib/bzpage.js b/data/lib/bzpage.js index d3250ba..87030e4 100644 --- a/data/lib/bzpage.js +++ b/data/lib/bzpage.js @@ -16,7 +16,8 @@ var ReporterColor = new Color(255, 255, 166); // RGB 255, 255, 166; HSL 60, 2, // global variables var config = {}; var constantData = {}; // This should be probably eliminated ASAP or - // or done by other means. TODO + // or done by other means. TODO +var equivalentComponents = null; /** * central handler processing messages from the main script. */ @@ -27,11 +28,13 @@ onMessage = function onMessage(msg) { document.location.reload(true); break; case "queryLocal": - queryInNewTab(msg.data, getComponent(), getProduct()); + queryInNewTab(msg.data, getComponent(), getProduct(), equivalentComponents); break; case "CreateButtons": constantData = msg.data.constData; config = msg.data.config; + equivalentComponents = ("equivalentComponents" in constantData) ? + constantData.equivalentComponents : null; generateButtons(msg.data.instPkgs, msg.data.kNodes); break; case "Error": diff --git a/data/lib/queries.js b/data/lib/queries.js index b43b616..b6e3661 100644 --- a/data/lib/queries.js +++ b/data/lib/queries.js @@ -22,16 +22,16 @@ function getSelection () { * @return None * */ -function queryInNewTab(text, component, product) { +function queryInNewTab(text, component, product, equivComps) { var urlStr = "https://" + window.location.hostname + "/buglist.cgi?query_format=advanced"; if (product) { urlStr += "&product=" + product.trim(); } if (component) { - if ("equivalentComponents" in constantData) { - var equivCompsArr = constantData.equivalentComponents. + if (equivComps) { + var equivCompsArr = equivComps. filter(function (REstr) { - return new RegExp(REstr).test(getComponent()); + return new RegExp(REstr).test(component); }, this); if (equivCompsArr.length > 0) { component = equivCompsArr[0]; @@ -52,7 +52,7 @@ function queryInNewTab(text, component, product) { + "&field0-0-2=status_whiteboard&type0-0-2=substring&value0-0-2=" + text; urlStr += searchText; - postMessage(new Message("OpenURLinTab", urlStr)); + postMessage(new Message("OpenURLinTab", urlStr)); // utils.js is always avaiulable } } @@ -65,6 +65,11 @@ function queryForSelection() { if (!text) { postMessage(new Message("GetClipboard", "queryLocal")); } else { - queryInNewTab(text, getComponent(), getProduct()); + if (equivalentComponents) { + queryInNewTab(text, getComponent(), getProduct(), equivalentComponents); + } + else { + queryInNewTab(text, getComponent(), getProduct()); + } } } -- cgit From 3c3860cd080dec5a71ae6c3c7bc3438fa8875d94 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 25 Mar 2011 15:01:26 +0100 Subject: Starting another module ... all small embelishments to the page. --- data/lib/otherButtons.js | 158 +++++++++++++++++++++++++++++++++++++++++++++++ data/lib/rhbzpage.js | 154 +-------------------------------------------- lib/main.js | 1 + 3 files changed, 162 insertions(+), 151 deletions(-) create mode 100644 data/lib/otherButtons.js diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js new file mode 100644 index 0000000..16adcea --- /dev/null +++ b/data/lib/otherButtons.js @@ -0,0 +1,158 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php +"use strict"; + +/** + * Find default assignee based on the current component + * + * @return String what would be a default assignee if + * we haven't set it up. + */ +function getDefaultAssignee() { + return filterByRegexp(constantData.defaultAssignee, + getComponent()).toLowerCase(); +} + +/** + * Set default assignee + * + * @return none + * sets this.defaultAssignee property according to defaultAssignee list + */ +function setDefaultAssignee() { + var defAss = getDefaultAssignee(); + + // Add setting default assignee + if ((defAss.length > 0) && (defAss !== getOwner())) { + createNewButton("bz_assignee_edit_container",true, { + "name": "Def. Assignee", + "assignee": "default" + }); + } +} + +function markBugTriaged() { + // https://fedoraproject.org/wiki/BugZappers/Meetings/Minutes-2009-Oct-27 + // http://meetbot.fedoraproject.org/fedora-meeting/2009-11-24\ + // /fedora-meeting.2009-11-24-15.11.log.html + // http://meetbot.fedoraproject.org/fedora-meeting/2009-11-24\ + // /fedora-meeting.2009-11-24-15.11.log.html + addStuffToTextBox("keywords","Triaged"); +} + +function addingEmbelishments(list) { + var FillMagicDoneRE = new RegExp("^\\s*\\[[0-9a-zA-Z_]*\\]"); + + var maintCCAddr = ""; + if (constantData.CCmaintainer) { + maintCCAddr = filterByRegexp(constantData.CCmaintainer, + getComponent())[0]; // filterByRegexp returns array, not string + } + + // we should make visible whether maintCCAddr is in CCList + if (maintCCAddr && isInList(maintCCAddr, getCCList())) { + var ccEditBoxElem = document.getElementById("cc_edit_area_showhide"); + ccEditBoxElem.style.color = "navy"; + ccEditBoxElem.style.fontWeight = "bolder"; + ccEditBoxElem.style.textDecoration = "underline"; + } + + // Take care of signature for Fedora bugzappers + if (config.signature && config.signature.length > 0) { + var signaturesCounter = 0; + var signatureFedoraString = config.signature; + document.forms.namedItem("changeform").addEventListener("submit", + function(aEvt) { + if (signaturesCounter < 1) { + addStuffToTextBox("comment", signatureFedoraString); + signaturesCounter += 1; + } + }, false); + } + + // set default assignee on change of the component + var compElement = document.getElementById("component"); + if (compElement && (compElement.options)) { + document.getElementById("component").addEventListener("change", + function() { + changeAssignee("default"); + }, false); + } + + // TODO Get compiz bugs as well + if ((constantData.chipNames) && + (list[0]) && + (!FillMagicDoneRE.test(getSummary())) && + (maintCCAddr === "xgl-maint@redhat.com")) { + // Add find chip magic button + var whiteboard_string = document.getElementById("status_whiteboard").value; + if (!/card_/.test(whiteboard_string)) { + fillInChipMagic(XorgLogAttList[0][1]); + } + } +} + +function setBranding(xLogAtts) { + var brandColor = {}; + var TriagedColor = {}; + + var ITbutton = document.getElementById("cf_issuetracker"); + var its = ITbutton ? ITbutton.value.trim() : ""; + + if (isEnterprise()) { + if (its && (its.length > 0)) { + brandColor = RHITColor; + } + else { + brandColor = RHColor; + } + } + else if (new RegExp("Fedora").test(document.getElementById("product").value)) { + if (document.getElementById("version").value === "rawhide") { + brandColor = RawhideColor; + } + else { + brandColor = FedoraColor; + } + } + + // Comment each of the following lines to get only partial branding + document.getElementsByTagName("body")[0].style.background = brandColor + .toString() + + " none"; + document.getElementById("titles").style.background = brandColor.toString() + + " none"; + + // Remove "Bug" from the title of the bug page, so we have more space with + // plenty of tabs + var titleElem = document.getElementsByTagName("title")[0]; + + titleElem.textContent = titleElem.textContent.slice(4); + var bodyTitleParent = document.getElementById("summary_alias_container").parentNode; + var bodyTitleElem = bodyTitleParent.getElementsByTagName("b")[0]; + bodyTitleElem.textContent = bodyTitleElem.textContent.slice(4); + + // Make background-color of the body of bug salmon pink + // for security bugs. + if (hasKeyword("Security")) { + document.getElementById("bugzilla-body").style.background = SalmonPink + .toString() + ' none'; + } + + // Make it visible whether the bug has been triaged + if (isTriaged()) { + document.getElementById("bz_field_status").style.background = brandColor + .lightColor().toString() + + " none"; + } + + var compElems; + if (config.suspiciousComponents + && isInList(getComponent(), config.suspiciousComponents) + && (compElems = document + .getElementById("bz_component_edit_container"))) { + compElems.style.background = "red none"; + } + + addingEmbelishments(xLogAtts); +} diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index f57af79..ddec25e 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -87,35 +87,6 @@ function RHOnMessageHandler(msg) { // RHBugzillaPage object -/** - * Find default assignee based on the current component - * - * @return String what would be a default assignee if - * we haven't set it up. - */ -function getDefaultAssignee() { - return filterByRegexp(constantData.defaultAssignee, - getComponent()).toLowerCase(); -} - -/** - * Set default assignee - * - * @return none - * sets this.defaultAssignee property according to defaultAssignee list - */ -function setDefaultAssignee() { - var defAss = getDefaultAssignee(); - - // Add setting default assignee - if ((defAss.length > 0) && (defAss !== getOwner())) { - createNewButton("bz_assignee_edit_container",true, { - "name": "Def. Assignee", - "assignee": "default" - }); - } -} - /** * Auxiliary function to compute more complicated resolution */ @@ -240,7 +211,7 @@ function pasteBacktraceInComments(atts) { createDeadLink ("callAbrtQuery_link", "Abrt bugs", mainTitle, abrtQueryURL, [], false, null, "a"); - + if (idContainsWord("cf_devel_whiteboard", 'btparsed')) { addStuffToTextBox('status_whiteboard', 'btparsed'); } @@ -253,7 +224,7 @@ function pasteBacktraceInComments(atts) { }); // TODO we need to go through all backtrace attachments, but // just the first one will do for now, we would need to do async - // parsing + // btAttachments.forEach(function(x) { var attURL = "https://bugzilla.redhat.com/attachment.cgi?id=" + x[1]; @@ -428,68 +399,6 @@ function isTriaged() { * @param its String with the IsueTracker numbers * @return none */ -function setBranding() { - var brandColor = {}; - var TriagedColor = {}; - - var ITbutton = document.getElementById("cf_issuetracker"); - var its = ITbutton ? ITbutton.value.trim() : ""; - - if (isEnterprise()) { - if (its && (its.length > 0)) { - brandColor = RHITColor; - } - else { - brandColor = RHColor; - } - } - else if (new RegExp("Fedora").test(document.getElementById("product").value)) { - if (document.getElementById("version").value === "rawhide") { - brandColor = RawhideColor; - } - else { - brandColor = FedoraColor; - } - } - - // Comment each of the following lines to get only partial branding - document.getElementsByTagName("body")[0].style.background = brandColor - .toString() - + " none"; - document.getElementById("titles").style.background = brandColor.toString() - + " none"; - - // Remove "Bug" from the title of the bug page, so we have more space with - // plenty of tabs - var titleElem = document.getElementsByTagName("title")[0]; - - titleElem.textContent = titleElem.textContent.slice(4); - var bodyTitleParent = document.getElementById("summary_alias_container").parentNode; - var bodyTitleElem = bodyTitleParent.getElementsByTagName("b")[0]; - bodyTitleElem.textContent = bodyTitleElem.textContent.slice(4); - - // Make background-color of the body of bug salmon pink - // for security bugs. - if (hasKeyword("Security")) { - document.getElementById("bugzilla-body").style.background = SalmonPink - .toString() + ' none'; - } - - // Make it visible whether the bug has been triaged - if (isTriaged()) { - document.getElementById("bz_field_status").style.background = brandColor - .lightColor().toString() - + " none"; - } - - var compElems; - if (config.suspiciousComponents - && isInList(getComponent(), config.suspiciousComponents) - && (compElems = document - .getElementById("bz_component_edit_container"))) { - compElems.style.background = "red none"; - } -} /** * @@ -837,15 +746,6 @@ function addClosingUpstream() { } } -function markBugTriaged() { - // https://fedoraproject.org/wiki/BugZappers/Meetings/Minutes-2009-Oct-27 - // http://meetbot.fedoraproject.org/fedora-meeting/2009-11-24\ - // /fedora-meeting.2009-11-24-15.11.log.html - // http://meetbot.fedoraproject.org/fedora-meeting/2009-11-24\ - // /fedora-meeting.2009-11-24-15.11.log.html - addStuffToTextBox("keywords","Triaged"); -} - /** * */ @@ -888,10 +788,8 @@ function parseBacktrace (ret) { function RHBZinit() { // inheritance ... call superobject's constructor var AbrtRE = new RegExp("^\\s*\\[abrt\\]"); - var FillMagicDoneRE = new RegExp("^\\s*\\[[0-9a-zA-Z_]*\\]"); var btSnippet = ""; - var signaturesCounter = 0; var chipMagicInterestingLine = ""; // getBadAttachments @@ -924,53 +822,7 @@ function RHBZinit() { // Just add a link to every Xorg.0.log link analyzing it. addCheckXorgLogLink(XorgLogAttList); - var maintCCAddr = ""; - if (constantData.CCmaintainer) { - maintCCAddr = filterByRegexp(constantData.CCmaintainer, - getComponent())[0]; // filterByRegexp returns array, not string - } - - // TODO Get compiz bugs as well - if ((constantData.chipNames) && - (XorgLogAttList[0]) && - (!FillMagicDoneRE.test(getSummary())) && - (maintCCAddr === "xgl-maint@redhat.com")) { - // Add find chip magic button - var whiteboard_string = document.getElementById("status_whiteboard").value; - if (!/card_/.test(whiteboard_string)) { - fillInChipMagic(XorgLogAttList[0][1]); - } - } - - // we should make visible whether maintCCAddr is in CCList - if (maintCCAddr && isInList(maintCCAddr, getCCList())) { - var ccEditBoxElem = document.getElementById("cc_edit_area_showhide"); - ccEditBoxElem.style.color = "navy"; - ccEditBoxElem.style.fontWeight = "bolder"; - ccEditBoxElem.style.textDecoration = "underline"; - } - - // Take care of signature for Fedora bugzappers - if (config.signature && config.signature.length > 0) { - var signatureFedoraString = config.signature; - document.forms.namedItem("changeform").addEventListener("submit", - function(aEvt) { - if (signaturesCounter < 1) { - addStuffToTextBox("comment", signatureFedoraString); - signaturesCounter += 1; - } - }, false); - } - setBranding(); - - // set default assignee on change of the component - var compElement = document.getElementById("component"); - if (compElement && (compElement.options)) { - document.getElementById("component").addEventListener("change", - function() { - changeAssignee("default"); - }, false); - } + setBranding(XorgLogAttList); // Uncheck "set default assignee" when the assignee is changed by other means document.getElementById("assigned_to").addEventListener("change", diff --git a/lib/main.js b/lib/main.js index 72a5fe8..6c91da1 100644 --- a/lib/main.js +++ b/lib/main.js @@ -121,6 +121,7 @@ var contentScriptLibraries = [ self.data.url("lib/viewSource.js"), self.data.url("lib/color.js"), self.data.url("lib/addNewLinks.js"), + self.data.url("lib/otherButtons.js"), self.data.url("lib/logging-front.js"), self.data.url('lib/bug-page-mod.js'), self.data.url("lib/rhbzpage.js"), -- cgit From 470e0d853724feb51a991e9e8b867e366c8519ae Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 25 Mar 2011 16:23:51 +0100 Subject: Cut out general bugzilla functions to a special module. --- data/lib/addAttachmentRow.js | 41 ++++ data/lib/bugzillaDOMFunctions.js | 372 ++++++++++++++++++++++++++++++++++++ data/lib/bzpage.js | 345 --------------------------------- data/lib/fixingAttMIME.js | 87 +++++++++ data/lib/makeBacktraceAttachment.js | 157 +++++++++++++++ data/lib/otherButtons.js | 8 + data/lib/queries.js | 34 +++- data/lib/rhbzpage.js | 369 +---------------------------------- data/lib/util.js | 13 ++ lib/main.js | 5 +- 10 files changed, 720 insertions(+), 711 deletions(-) create mode 100644 data/lib/addAttachmentRow.js create mode 100644 data/lib/bugzillaDOMFunctions.js create mode 100644 data/lib/fixingAttMIME.js create mode 100644 data/lib/makeBacktraceAttachment.js 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 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 * @@ -615,39 +370,6 @@ function getOptionTableCell(tableId, label) { return null; } -/** - * 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 * @@ -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 to perform + * MIME type change on. "mime_type" => "", # 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 + * 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="" + this.login + ""; + } + + 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="" + this.login + ""; - } - - 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,78 +166,15 @@ 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 * @@ -593,107 +335,6 @@ function findInterestingLine(wholeLog, backMsg) { logAnalyzeLogic[backMsg].func(results); } -/** - * 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 to perform - * MIME type change on. "mime_type" => "", # 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 - * 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. * @@ -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 @@ -80,6 +80,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 * 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"), -- cgit From 71fc5197d1a71a9f2efd1b4f83c7d3b0de539e10 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 25 Mar 2011 19:19:07 +0100 Subject: Fix order of parameters of fixAttachById function. XMLRPCURL is mandatory. Fixes #73 --- data/lib/fixingAttMIME.js | 2 +- data/lib/otherButtons.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/lib/fixingAttMIME.js b/data/lib/fixingAttMIME.js index 9297c06..99c32f7 100644 --- a/data/lib/fixingAttMIME.js +++ b/data/lib/fixingAttMIME.js @@ -43,7 +43,7 @@ function XMLRPCcallback() { * this change }; * */ -function fixAttachById(id, type, email, XMLRPCURL) { +function fixAttachById(id, XMLRPCURL, type, email) { var params = []; if (type === undefined) { diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js index b7bb7d5..bc445bf 100644 --- a/data/lib/otherButtons.js +++ b/data/lib/otherButtons.js @@ -87,7 +87,7 @@ function addingEmbelishments(list) { // Add find chip magic button var whiteboard_string = document.getElementById("status_whiteboard").value; if (!/card_/.test(whiteboard_string)) { - fillInChipMagic(XorgLogAttList[0][1]); + fillInChipMagic(list[0][1]); } } } -- cgit From fb9466fb0147ae296d0657cda851ae707f5453d4 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 25 Mar 2011 20:23:55 +0100 Subject: Make new links work on RH BZ. Fix #74 --- data/lib/addNewLinks.js | 8 ++++++++ data/lib/bug-page-mod.js | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/data/lib/addNewLinks.js b/data/lib/addNewLinks.js index 7993e07..020dbb3 100644 --- a/data/lib/addNewLinks.js +++ b/data/lib/addNewLinks.js @@ -36,6 +36,9 @@ * ***** END LICENSE BLOCK ***** */ function addNewLinks(d) { + // Why we are using d.querySelector for something which could be + // getElementById().value? FIXME + // console.log("addNewLinks : product = " + document.getElementById("product").value); var product = d.querySelector("#field_container_product option[selected]"); var component = d.querySelector("#component option[selected]"); @@ -54,6 +57,11 @@ function addNewLinks(d) { var url = 'enter_bug.cgi?product=' + encodeURIComponent(product.value) + '&component=' + encodeURIComponent(component.value); if (label) { + var componentElement = document.getElementById("bz_component_input"); + var computedStyle = window.getComputedStyle(componentElement); + if (computedStyle.display == "none") { + label = document.getElementById("bz_component_edit_container"); + }; createDeadLink("file_new_bug_component", "new", label, url, [], "parens"); } } diff --git a/data/lib/bug-page-mod.js b/data/lib/bug-page-mod.js index 589a45f..8972ee6 100644 --- a/data/lib/bug-page-mod.js +++ b/data/lib/bug-page-mod.js @@ -37,8 +37,8 @@ function tweakBugzilla(d) { // run on both bugzilla.m.o and bugzilla-stage-tip.m.o - if (!onBugzillaPage(d.URL)) - return; + // if (!onBugzillaPage(d.URL)) + // return; // Put the quicksearch text in the quicksearch boxes quicksearchHandler(d); -- cgit From 0916a6ecf53909dc617cd0d22bc62c4c0466da0a Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Mon, 28 Mar 2011 16:21:27 +0200 Subject: Playing with pitz. --- pitzdir/hooks/after_saving_entities_to_yaml_files.example | 6 ++++++ pitzdir/person-d1919a9d-e596-4654-b082-a39837b4756f.yaml | 11 +++++++++++ pitzdir/status-1a2999d5-feec-46a6-9c3e-7791397a86eb.yaml | 11 +++++++++++ pitzdir/status-3fbe66b0-0887-4ea0-9368-7740b7cce611.yaml | 11 +++++++++++ pitzdir/status-780866dd-9d16-4944-ba37-8d05d6a41d06.yaml | 11 +++++++++++ pitzdir/status-82d7bd4f-8366-410f-83c1-ae85ac8c1b78.yaml | 11 +++++++++++ pitzdir/status-9359a849-7e1c-4473-bc1f-bd985c689e17.yaml | 13 +++++++++++++ pitzdir/status-af6adcca-3e22-4827-a62e-4b4063f72701.yaml | 13 +++++++++++++ 8 files changed, 87 insertions(+) create mode 100644 pitzdir/hooks/after_saving_entities_to_yaml_files.example create mode 100644 pitzdir/person-d1919a9d-e596-4654-b082-a39837b4756f.yaml create mode 100644 pitzdir/status-1a2999d5-feec-46a6-9c3e-7791397a86eb.yaml create mode 100644 pitzdir/status-3fbe66b0-0887-4ea0-9368-7740b7cce611.yaml create mode 100644 pitzdir/status-780866dd-9d16-4944-ba37-8d05d6a41d06.yaml create mode 100644 pitzdir/status-82d7bd4f-8366-410f-83c1-ae85ac8c1b78.yaml create mode 100644 pitzdir/status-9359a849-7e1c-4473-bc1f-bd985c689e17.yaml create mode 100644 pitzdir/status-af6adcca-3e22-4827-a62e-4b4063f72701.yaml diff --git a/pitzdir/hooks/after_saving_entities_to_yaml_files.example b/pitzdir/hooks/after_saving_entities_to_yaml_files.example new file mode 100644 index 0000000..1d28d5b --- /dev/null +++ b/pitzdir/hooks/after_saving_entities_to_yaml_files.example @@ -0,0 +1,6 @@ +#! /bin/bash + +# Make this file executable to enable it. +echo "Starting the after_saving_entities_to_yaml_files hook..." +git add $1/. +echo "Finished the after_saving_entities_to_yaml_files hook." diff --git a/pitzdir/person-d1919a9d-e596-4654-b082-a39837b4756f.yaml b/pitzdir/person-d1919a9d-e596-4654-b082-a39837b4756f.yaml new file mode 100644 index 0000000..0c12f82 --- /dev/null +++ b/pitzdir/person-d1919a9d-e596-4654-b082-a39837b4756f.yaml @@ -0,0 +1,11 @@ +attached_files: [] +created_time: 2011-03-28 16:14:07.646631 +description: '' +html_file_saved: &id001 2011-03-28 16:15:22.032692 +modified_time: *id001 +pscore: 0 +title: matej +type: person +uuid: !!python/object:uuid.UUID + int: 278564670164489182789708313982187894127 +yaml_file_saved: 2011-03-28 16:15:22.094699 diff --git a/pitzdir/status-1a2999d5-feec-46a6-9c3e-7791397a86eb.yaml b/pitzdir/status-1a2999d5-feec-46a6-9c3e-7791397a86eb.yaml new file mode 100644 index 0000000..d1614a1 --- /dev/null +++ b/pitzdir/status-1a2999d5-feec-46a6-9c3e-7791397a86eb.yaml @@ -0,0 +1,11 @@ +attached_files: [] +created_time: 2011-03-28 16:14:05.477512 +description: '' +html_file_saved: &id001 2011-03-28 16:15:21.808949 +modified_time: *id001 +pscore: 40 +title: paused +type: status +uuid: !!python/object:uuid.UUID + int: 34775932224770547499270089907461850859 +yaml_file_saved: 2011-03-28 16:15:22.079313 diff --git a/pitzdir/status-3fbe66b0-0887-4ea0-9368-7740b7cce611.yaml b/pitzdir/status-3fbe66b0-0887-4ea0-9368-7740b7cce611.yaml new file mode 100644 index 0000000..8b5466b --- /dev/null +++ b/pitzdir/status-3fbe66b0-0887-4ea0-9368-7740b7cce611.yaml @@ -0,0 +1,11 @@ +attached_files: [] +created_time: 2011-03-28 16:14:05.478043 +description: '' +html_file_saved: &id001 2011-03-28 16:15:21.896624 +modified_time: *id001 +pscore: 20 +title: unstarted +type: status +uuid: !!python/object:uuid.UUID + int: 84729982890146948594172620138817054225 +yaml_file_saved: 2011-03-28 16:15:22.084955 diff --git a/pitzdir/status-780866dd-9d16-4944-ba37-8d05d6a41d06.yaml b/pitzdir/status-780866dd-9d16-4944-ba37-8d05d6a41d06.yaml new file mode 100644 index 0000000..8077654 --- /dev/null +++ b/pitzdir/status-780866dd-9d16-4944-ba37-8d05d6a41d06.yaml @@ -0,0 +1,11 @@ +attached_files: [] +created_time: 2011-03-28 16:14:05.477778 +description: '' +html_file_saved: &id001 2011-03-28 16:15:21.475995 +modified_time: *id001 +pscore: 30 +title: queued +type: status +uuid: !!python/object:uuid.UUID + int: 159550984232877760402819834796092693766 +yaml_file_saved: 2011-03-28 16:15:22.075979 diff --git a/pitzdir/status-82d7bd4f-8366-410f-83c1-ae85ac8c1b78.yaml b/pitzdir/status-82d7bd4f-8366-410f-83c1-ae85ac8c1b78.yaml new file mode 100644 index 0000000..92d23e7 --- /dev/null +++ b/pitzdir/status-82d7bd4f-8366-410f-83c1-ae85ac8c1b78.yaml @@ -0,0 +1,11 @@ +attached_files: [] +created_time: 2011-03-28 16:14:05.476964 +description: '' +html_file_saved: &id001 2011-03-28 16:15:21.852914 +modified_time: *id001 +pscore: 50 +title: started +type: status +uuid: !!python/object:uuid.UUID + int: 173919822951730134170435275657663224696 +yaml_file_saved: 2011-03-28 16:15:22.082162 diff --git a/pitzdir/status-9359a849-7e1c-4473-bc1f-bd985c689e17.yaml b/pitzdir/status-9359a849-7e1c-4473-bc1f-bd985c689e17.yaml new file mode 100644 index 0000000..6ec7f0e --- /dev/null +++ b/pitzdir/status-9359a849-7e1c-4473-bc1f-bd985c689e17.yaml @@ -0,0 +1,13 @@ +attached_files: [] +created_by: !!python/object:uuid.UUID + int: 278564670164489182789708313982187894127 +created_time: 2011-03-28 16:14:05.461110 +description: '' +html_file_saved: &id001 2011-03-28 16:15:21.987882 +modified_time: *id001 +pscore: 100 +title: finished +type: status +uuid: !!python/object:uuid.UUID + int: 195862043068290794414017573255614340631 +yaml_file_saved: 2011-03-28 16:15:22.091386 diff --git a/pitzdir/status-af6adcca-3e22-4827-a62e-4b4063f72701.yaml b/pitzdir/status-af6adcca-3e22-4827-a62e-4b4063f72701.yaml new file mode 100644 index 0000000..6a258ae --- /dev/null +++ b/pitzdir/status-af6adcca-3e22-4827-a62e-4b4063f72701.yaml @@ -0,0 +1,13 @@ +attached_files: [] +created_by: !!python/object:uuid.UUID + int: 278564670164489182789708313982187894127 +created_time: 2011-03-28 16:14:05.478331 +description: '' +html_file_saved: &id001 2011-03-28 16:15:21.941792 +modified_time: *id001 +pscore: 10 +title: abandoned +type: status +uuid: !!python/object:uuid.UUID + int: 233169760882796115564254598792274716417 +yaml_file_saved: 2011-03-28 16:15:22.087881 -- cgit From 00c28a3061f196b66972069101ab66e2c99dfe90 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Tue, 29 Mar 2011 17:48:13 +0200 Subject: Don't mess with cursor. --- data/lib/rhbzpage.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index 81116ba..4adb6ea 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -296,7 +296,6 @@ function analyzeXorg(results) { innerString += "No matching lines found!"; } - document.body.style.cursor = "auto"; postMessage(new Message("OpenStringInPanel", '' + "Xorg.0.log analysis
\n" +
@@ -305,7 +304,6 @@ function analyzeXorg(results) {
 }
 
 function analyzeXorgLog(attachID, backMsg) {
-  document.body.style.cursor = "wait";
   postMessage(new Message("GetURL", {
     url: "https://" + window.location.hostname + "/attachment.cgi?id=" + attachID,
     backMessage: backMsg
-- 
cgit 


From 8bf1efb83b09258433af73c7fa46edfe84f29c68 Mon Sep 17 00:00:00 2001
From: Matěj Cepl 
Date: Wed, 30 Mar 2011 01:51:00 +0200
Subject: Bump the release version to make it higher than 0.92

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 1fbb0f3..e208c36 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
     "description": "Additional buttons and other function helping in the triage on bugzilla",
     "author": "Matej Cepl (http://matej.ceplovi.cz)",
     "license": "MIT/X11 (http://opensource.org/licenses/mit-license.php) and MPL",
-    "version": "0.92",
+    "version": "0.93",
     "contributors": [
       "Ehsan Akhgari (http://ehsanakhgari.org/) ",
       "Johnathan Nightingale (http://johnath.com) ",
-- 
cgit 


From 7821fb333377cbd3fce916c79e232ece6c8903e6 Mon Sep 17 00:00:00 2001
From: Matěj Cepl 
Date: Wed, 30 Mar 2011 02:53:18 +0200
Subject: Add logging to find out what's going on the computed style.

---
 data/lib/addNewLinks.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/data/lib/addNewLinks.js b/data/lib/addNewLinks.js
index 020dbb3..735a0fc 100644
--- a/data/lib/addNewLinks.js
+++ b/data/lib/addNewLinks.js
@@ -59,6 +59,7 @@ function addNewLinks(d) {
     if (label) {
       var componentElement = document.getElementById("bz_component_input");
       var computedStyle = window.getComputedStyle(componentElement);
+      console.log("computedStyle.display = " + computedStyle.display);
       if (computedStyle.display == "none") {
         label = document.getElementById("bz_component_edit_container");
       };
-- 
cgit 


From d82ae1ac86607cf902b874c60de55136127520a7 Mon Sep 17 00:00:00 2001
From: Matěj Cepl 
Date: Wed, 30 Mar 2011 03:11:58 +0200
Subject: Fix Sandybridge spelling.

---
 chip-data/chipNames.json | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/chip-data/chipNames.json b/chip-data/chipNames.json
index b9bbc7c..ed78655 100644
--- a/chip-data/chipNames.json
+++ b/chip-data/chipNames.json
@@ -550,12 +550,12 @@
     "8086,0046":["Arrandale"],
     "8086,0080":["Ivy_Bridge"],
     "8086,0000":["Larrabee"],
-    "8086,0102":["Sandy_Bridge"],
-    "8086,0106":["Sandy_Bridge"],
-    "8086,0112":["Sandy_Bridge"],
-    "8086,0116":["Sandy_Bridge"],
-    "8086,0122":["Sandy_Bridge"],
-    "8086,0126":["Sandy_Bridge"],
-    "8086,010A":["Sandy_Bridge"],
+    "8086,0102":["Sandybridge"],
+    "8086,0106":["Sandybridge"],
+    "8086,0112":["Sandybridge"],
+    "8086,0116":["Sandybridge"],
+    "8086,0122":["Sandybridge"],
+    "8086,0126":["Sandybridge"],
+    "8086,010A":["Sandybridge"],
     "15AD:0405":["VMware_SVGA_II"]
 }
-- 
cgit 


From 461f09665a6a9be7700237f6b458b65ca38061d5 Mon Sep 17 00:00:00 2001
From: Matěj Cepl 
Date: Thu, 31 Mar 2011 00:35:44 +0200
Subject: Fix order of covering elements in createDeadLink.

---
 data/lib/util.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/data/lib/util.js b/data/lib/util.js
index 611d353..6256171 100644
--- a/data/lib/util.js
+++ b/data/lib/util.js
@@ -140,10 +140,10 @@ function createDeadLink (id, text, parent, callback, params, before, covered, ac
   locParent.appendChild(newAElem);
 
   if ((before === "br") || (before === true)) {
-    locParent.appendChild(document.createElement("br"));
+    locParent.insertBefore(document.createElement("br"), newAElem);
   }
   else if (before === "dash") {
-    locParent.appendChild(document.createTextNode("\u00A0-\u00A0"));
+    locParent.insertBefore(document.createTextNode("\u00A0-\u00A0"), newAElem);
   }
   else if (before === "parens") {
     locParent.appendChild(document.createTextNode(")"));
-- 
cgit 


From e9461083b1abcc1bbc9f710c18bdf56fdedb1a83 Mon Sep 17 00:00:00 2001
From: Matěj Cepl 
Date: Mon, 4 Apr 2011 00:01:53 +0200
Subject: Move marking reporter's to otherButtons module.

---
 data/lib/bzpage.js       | 23 -----------------------
 data/lib/otherButtons.js | 23 +++++++++++++++++++++++
 2 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/data/lib/bzpage.js b/data/lib/bzpage.js
index d65c232..f99d60c 100644
--- a/data/lib/bzpage.js
+++ b/data/lib/bzpage.js
@@ -324,29 +324,6 @@ function setConfigurationButton () {
   }, false);
 }
 
-/**
- * Set background color of all comments made by reporter in ReporterColor color
- *
- */
-function checkComments () {
-  var reporter = getReporter();
-  commentsWalker(function(x) {
-    var email = parseMailto(x.getElementsByClassName("vcard")[0]
-        .getElementsByTagName("a")[0]);
-    if (email.indexOf(reporter) != -1) {
-      x.style.backgroundColor = ReporterColor.toString();
-    }
-  });
-}
-
-function collectComments () {
-  var outStr = "";
-  commentsWalker(function(x) {
-    outStr += x.getElementsByTagName("pre")[0].textContent + "\n";
-  });
-  return outStr.trim();
-}
-
 /**
  * dd
  *
diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js
index bc445bf..3a1f76a 100644
--- a/data/lib/otherButtons.js
+++ b/data/lib/otherButtons.js
@@ -2,6 +2,29 @@
 // http://www.opensource.org/licenses/mit-license.php
 "use strict";
 
+/**
+ * Set background color of all comments made by reporter in ReporterColor color
+ *
+ */
+function checkComments () {
+  var reporter = getReporter();
+  commentsWalker(function(x) {
+    var email = parseMailto(x.getElementsByClassName("vcard")[0]
+        .getElementsByTagName("a")[0]);
+    if (email.indexOf(reporter) != -1) {
+      x.style.backgroundColor = ReporterColor.toString();
+    }
+  });
+}
+
+function collectComments () {
+  var outStr = "";
+  commentsWalker(function(x) {
+    outStr += x.getElementsByTagName("pre")[0].textContent + "\n";
+  });
+  return outStr.trim();
+}
+
 /**
  * Find default assignee based on the current component
  *
-- 
cgit 


From d0eb80db9a8839dabe0a9c24fdab38bdd66c97dd Mon Sep 17 00:00:00 2001
From: Matěj Cepl 
Date: Mon, 4 Apr 2011 22:44:48 +0200
Subject: Get rid of pitz, it is for playing not for real work.

---
 pitzdir/hooks/after_saving_entities_to_yaml_files.example |  6 ------
 pitzdir/person-d1919a9d-e596-4654-b082-a39837b4756f.yaml  | 11 -----------
 pitzdir/status-1a2999d5-feec-46a6-9c3e-7791397a86eb.yaml  | 11 -----------
 pitzdir/status-3fbe66b0-0887-4ea0-9368-7740b7cce611.yaml  | 11 -----------
 pitzdir/status-780866dd-9d16-4944-ba37-8d05d6a41d06.yaml  | 11 -----------
 pitzdir/status-82d7bd4f-8366-410f-83c1-ae85ac8c1b78.yaml  | 11 -----------
 pitzdir/status-9359a849-7e1c-4473-bc1f-bd985c689e17.yaml  | 13 -------------
 pitzdir/status-af6adcca-3e22-4827-a62e-4b4063f72701.yaml  | 13 -------------
 8 files changed, 87 deletions(-)
 delete mode 100644 pitzdir/hooks/after_saving_entities_to_yaml_files.example
 delete mode 100644 pitzdir/person-d1919a9d-e596-4654-b082-a39837b4756f.yaml
 delete mode 100644 pitzdir/status-1a2999d5-feec-46a6-9c3e-7791397a86eb.yaml
 delete mode 100644 pitzdir/status-3fbe66b0-0887-4ea0-9368-7740b7cce611.yaml
 delete mode 100644 pitzdir/status-780866dd-9d16-4944-ba37-8d05d6a41d06.yaml
 delete mode 100644 pitzdir/status-82d7bd4f-8366-410f-83c1-ae85ac8c1b78.yaml
 delete mode 100644 pitzdir/status-9359a849-7e1c-4473-bc1f-bd985c689e17.yaml
 delete mode 100644 pitzdir/status-af6adcca-3e22-4827-a62e-4b4063f72701.yaml

diff --git a/pitzdir/hooks/after_saving_entities_to_yaml_files.example b/pitzdir/hooks/after_saving_entities_to_yaml_files.example
deleted file mode 100644
index 1d28d5b..0000000
--- a/pitzdir/hooks/after_saving_entities_to_yaml_files.example
+++ /dev/null
@@ -1,6 +0,0 @@
-#! /bin/bash
-
-# Make this file executable to enable it.
-echo "Starting the after_saving_entities_to_yaml_files hook..."
-git add $1/.
-echo "Finished the after_saving_entities_to_yaml_files hook."
diff --git a/pitzdir/person-d1919a9d-e596-4654-b082-a39837b4756f.yaml b/pitzdir/person-d1919a9d-e596-4654-b082-a39837b4756f.yaml
deleted file mode 100644
index 0c12f82..0000000
--- a/pitzdir/person-d1919a9d-e596-4654-b082-a39837b4756f.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-attached_files: []
-created_time: 2011-03-28 16:14:07.646631
-description: ''
-html_file_saved: &id001 2011-03-28 16:15:22.032692
-modified_time: *id001
-pscore: 0
-title: matej
-type: person
-uuid: !!python/object:uuid.UUID
-  int: 278564670164489182789708313982187894127
-yaml_file_saved: 2011-03-28 16:15:22.094699
diff --git a/pitzdir/status-1a2999d5-feec-46a6-9c3e-7791397a86eb.yaml b/pitzdir/status-1a2999d5-feec-46a6-9c3e-7791397a86eb.yaml
deleted file mode 100644
index d1614a1..0000000
--- a/pitzdir/status-1a2999d5-feec-46a6-9c3e-7791397a86eb.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-attached_files: []
-created_time: 2011-03-28 16:14:05.477512
-description: ''
-html_file_saved: &id001 2011-03-28 16:15:21.808949
-modified_time: *id001
-pscore: 40
-title: paused
-type: status
-uuid: !!python/object:uuid.UUID
-  int: 34775932224770547499270089907461850859
-yaml_file_saved: 2011-03-28 16:15:22.079313
diff --git a/pitzdir/status-3fbe66b0-0887-4ea0-9368-7740b7cce611.yaml b/pitzdir/status-3fbe66b0-0887-4ea0-9368-7740b7cce611.yaml
deleted file mode 100644
index 8b5466b..0000000
--- a/pitzdir/status-3fbe66b0-0887-4ea0-9368-7740b7cce611.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-attached_files: []
-created_time: 2011-03-28 16:14:05.478043
-description: ''
-html_file_saved: &id001 2011-03-28 16:15:21.896624
-modified_time: *id001
-pscore: 20
-title: unstarted
-type: status
-uuid: !!python/object:uuid.UUID
-  int: 84729982890146948594172620138817054225
-yaml_file_saved: 2011-03-28 16:15:22.084955
diff --git a/pitzdir/status-780866dd-9d16-4944-ba37-8d05d6a41d06.yaml b/pitzdir/status-780866dd-9d16-4944-ba37-8d05d6a41d06.yaml
deleted file mode 100644
index 8077654..0000000
--- a/pitzdir/status-780866dd-9d16-4944-ba37-8d05d6a41d06.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-attached_files: []
-created_time: 2011-03-28 16:14:05.477778
-description: ''
-html_file_saved: &id001 2011-03-28 16:15:21.475995
-modified_time: *id001
-pscore: 30
-title: queued
-type: status
-uuid: !!python/object:uuid.UUID
-  int: 159550984232877760402819834796092693766
-yaml_file_saved: 2011-03-28 16:15:22.075979
diff --git a/pitzdir/status-82d7bd4f-8366-410f-83c1-ae85ac8c1b78.yaml b/pitzdir/status-82d7bd4f-8366-410f-83c1-ae85ac8c1b78.yaml
deleted file mode 100644
index 92d23e7..0000000
--- a/pitzdir/status-82d7bd4f-8366-410f-83c1-ae85ac8c1b78.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-attached_files: []
-created_time: 2011-03-28 16:14:05.476964
-description: ''
-html_file_saved: &id001 2011-03-28 16:15:21.852914
-modified_time: *id001
-pscore: 50
-title: started
-type: status
-uuid: !!python/object:uuid.UUID
-  int: 173919822951730134170435275657663224696
-yaml_file_saved: 2011-03-28 16:15:22.082162
diff --git a/pitzdir/status-9359a849-7e1c-4473-bc1f-bd985c689e17.yaml b/pitzdir/status-9359a849-7e1c-4473-bc1f-bd985c689e17.yaml
deleted file mode 100644
index 6ec7f0e..0000000
--- a/pitzdir/status-9359a849-7e1c-4473-bc1f-bd985c689e17.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-attached_files: []
-created_by: !!python/object:uuid.UUID
-  int: 278564670164489182789708313982187894127
-created_time: 2011-03-28 16:14:05.461110
-description: ''
-html_file_saved: &id001 2011-03-28 16:15:21.987882
-modified_time: *id001
-pscore: 100
-title: finished
-type: status
-uuid: !!python/object:uuid.UUID
-  int: 195862043068290794414017573255614340631
-yaml_file_saved: 2011-03-28 16:15:22.091386
diff --git a/pitzdir/status-af6adcca-3e22-4827-a62e-4b4063f72701.yaml b/pitzdir/status-af6adcca-3e22-4827-a62e-4b4063f72701.yaml
deleted file mode 100644
index 6a258ae..0000000
--- a/pitzdir/status-af6adcca-3e22-4827-a62e-4b4063f72701.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-attached_files: []
-created_by: !!python/object:uuid.UUID
-  int: 278564670164489182789708313982187894127
-created_time: 2011-03-28 16:14:05.478331
-description: ''
-html_file_saved: &id001 2011-03-28 16:15:21.941792
-modified_time: *id001
-pscore: 10
-title: abandoned
-type: status
-uuid: !!python/object:uuid.UUID
-  int: 233169760882796115564254598792274716417
-yaml_file_saved: 2011-03-28 16:15:22.087881
-- 
cgit 


From 67ab098bf0ad332c651e79919f728e4f276ed918 Mon Sep 17 00:00:00 2001
From: Matěj Cepl 
Date: Thu, 7 Apr 2011 19:40:24 +0200
Subject: Don't create new elements, just add relational s.

---
 data/lib/jumpNextBug.js | 54 +++++++++++++++++++++++++++++++++++++++----------
 lib/main.js             |  2 +-
 2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/data/lib/jumpNextBug.js b/data/lib/jumpNextBug.js
index af0ff39..8f64b0d 100644
--- a/data/lib/jumpNextBug.js
+++ b/data/lib/jumpNextBug.js
@@ -1,15 +1,47 @@
 // Released under the MIT/X11 license
 // http://www.opensource.org/licenses/mit-license.php
 "use strict";
-var nextElement = {};
-var nextRE = new RegExp("Next");
 
-var aNavigElements = document.querySelectorAll("#bugzilla-body .navigation a");
-var filteredElements = Array.filter(aNavigElements, function(elem) {
-  return nextRE.test(elem.textContent);
-});
-if (filteredElements.length > 0) {
-  nextElement = filteredElements[0];
-  nextElement.setAttribute("accesskey", "n");
-  nextElement.innerHTML = "Next";
-}
+(function createRelationElements() {
+  var relation = {};
+  var linkLabels = ["First", "Last", "Prev", "Next"];
+  var labelToRelation = {
+    "First": {
+      rel: "start"
+    },
+    "Last": {
+      rel: "last"
+    },
+    "Prev": {
+      rel: "prev"
+    },
+    "Next": {
+      rel: "next"
+    }
+  };
+
+  function createLinkRel (rel, href) {
+    var newLinkElement = document.createElement("link");
+    newLinkElement.setAttribute("rel", rel);
+    newLinkElement.setAttribute("href", href);
+    document.getElementsByTagName("head")[0].
+      appendChild(newLinkElement);
+  }
+
+  var aNavigElements = document.querySelectorAll("#bugzilla-body .navigation a");
+  Array.forEach(aNavigElements, function(elem) {
+      var labelText = elem.textContent.trim();
+      if (isInList(labelText, linkLabels)) {
+        labelToRelation[labelText].href = elem.getAttribute("href");
+      };
+  });
+  console.log("labelToRelation = " + labelToRelation.toSource());
+  for (var key in labelToRelation) {
+    if (labelToRelation.hasOwnProperty(key)) {
+      relation = labelToRelation[key];
+      if (relation.href) {
+        createLinkRel(relation.rel, relation.href);
+      }
+    }
+  }
+})();
diff --git a/lib/main.js b/lib/main.js
index 80144cc..f3de753 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -114,8 +114,8 @@ var messageHandler = exports.messageHandler = function messageHandler(worker, ms
 
 var contentScriptLibraries = [
   self.data.url('lib/urltest.js'),
-  self.data.url("lib/jumpNextBug.js"),
   self.data.url("lib/util.js"),
+  self.data.url("lib/jumpNextBug.js"),
   self.data.url("lib/queries.js"),
   self.data.url("lib/preprocessDuplicates.js"),
   self.data.url("lib/viewSource.js"),
-- 
cgit 


From 26fc9ed67392805abcfeec21f0007e5b3c160708 Mon Sep 17 00:00:00 2001
From: Matěj Cepl 
Date: Thu, 7 Apr 2011 19:40:24 +0200
Subject: Don't create new elements, just add relational s.

---
 data/lib/jumpNextBug.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/data/lib/jumpNextBug.js b/data/lib/jumpNextBug.js
index 8f64b0d..2e097a3 100644
--- a/data/lib/jumpNextBug.js
+++ b/data/lib/jumpNextBug.js
@@ -35,7 +35,7 @@
         labelToRelation[labelText].href = elem.getAttribute("href");
       };
   });
-  console.log("labelToRelation = " + labelToRelation.toSource());
+
   for (var key in labelToRelation) {
     if (labelToRelation.hasOwnProperty(key)) {
       relation = labelToRelation[key];
-- 
cgit 


From 03eb77511381d3648bc4375d16e4b55cdb7dd0b3 Mon Sep 17 00:00:00 2001
From: Matěj Cepl 
Date: Thu, 7 Apr 2011 20:08:35 +0200
Subject: Make a new bug link for the current component independent of BZ
 instance.

---
 data/lib/addNewLinks.js | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/data/lib/addNewLinks.js b/data/lib/addNewLinks.js
index 735a0fc..02bd658 100644
--- a/data/lib/addNewLinks.js
+++ b/data/lib/addNewLinks.js
@@ -36,9 +36,6 @@
  * ***** END LICENSE BLOCK ***** */
 
 function addNewLinks(d) {
-  // Why we are using d.querySelector for something which could be
-  // getElementById().value? FIXME
-  // console.log("addNewLinks : product = " + document.getElementById("product").value);
   var product = d.querySelector("#field_container_product option[selected]");
   var component = d.querySelector("#component option[selected]");
 
@@ -58,11 +55,15 @@ function addNewLinks(d) {
       '&component=' + encodeURIComponent(component.value);
     if (label) {
       var componentElement = document.getElementById("bz_component_input");
-      var computedStyle = window.getComputedStyle(componentElement);
-      console.log("computedStyle.display = " + computedStyle.display);
-      if (computedStyle.display == "none") {
-        label = document.getElementById("bz_component_edit_container");
-      };
+      if (componentElement) { // We are in the Red Hat bugzilla
+      // do we have components list visible?
+        if (document.getElementById('bz_component_input').
+          classList.contains("bz_default_hidden")) {
+            label = document.getElementById("bz_component_edit_container");
+          }
+      } else {
+        label = document.getElementById('component').parentNode;
+      }
       createDeadLink("file_new_bug_component", "new", label, url, [], "parens");
     }
   }
-- 
cgit 


From 4d29c8b4eb1f3e66da8d60fd1f42f3e4c06d2b39 Mon Sep 17 00:00:00 2001
From: Matěj Cepl 
Date: Sat, 16 Apr 2011 20:55:52 +0200
Subject: Generate better  for the timesheet.

---
 lib/logger.js | 14 +++++++++++++-
 lib/xmlrpc.js | 43 +++++++++++++++++++++++--------------------
 2 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/lib/logger.js b/lib/logger.js
index 19fabb5..7e0c516 100644
--- a/lib/logger.js
+++ b/lib/logger.js
@@ -79,13 +79,25 @@ exports.generateTimeSheet = function generateTimeSheet() {
 }; 
 
 function timeSheetRecordsPrinter(records) {
+  function leadingZero(n) {
+    // pads a single number with a leading zero. Heh.
+    var s = n.toString();
+    if (s.length === 1) {
+      s = "0" + s;
+    }
+    return s;
+  }
+
   var commentBugRE = new RegExp("[bB]ug\\s+([0-9]+)","g");
   // sort the records into temporary array
   var tmpArr = [];
+  var today = new Date();
+  var todayStr = today.getFullYear()+"-"+leadingZero(today.getMonth()+1)+
+    "-"+leadingZero(today.getDate());
   var outStr = '<!DOCTYPE html>' +
     "<html><head>\n"+
     "<meta charset='utf-8'/>\n"+
-    "<title>Status report\n\n\n" +
+    "TimeSheet-"+ todayStr + "\n\n\n" +
     "

TimeSheet

\n"; for (var i in records) { diff --git a/lib/xmlrpc.js b/lib/xmlrpc.js index 8b71f32..6576f31 100644 --- a/lib/xmlrpc.js +++ b/lib/xmlrpc.js @@ -26,6 +26,29 @@ * not an instance of SAME Array. */ +var dateToISO8601 = exports.dateToISO8601 = function dateToISO8601(date) { + function leadingZero(n) { + // pads a single number with a leading zero. Heh. + if (n.length === 1) { + n = "0" + n; + } + return n; + } + + // wow I hate working with the Date object + console.log("date = " + date); + var year = date.getYear(); + var month = leadingZero(date.getMonth()); + var day = leadingZero(date.getDate()); + var time = leadingZero(date.getHours()) + + ":" + leadingZero(date.getMinutes()) + + ":" + leadingZero(date.getSeconds()); + + var converted = year + month + day + "T" + time; + console.log("date = " + converted); + return converted; +}; + var XMLRPCMessage = exports.XMLRPCMessage = function XMLRPCMessage(methodname) { this.method = methodname || "system.listMethods"; this.params = []; @@ -115,26 +138,6 @@ XMLRPCMessage.prototype.doBooleanXML = function (data) { }; XMLRPCMessage.prototype.doDateXML = function (data) { - function leadingZero(n) { - // pads a single number with a leading zero. Heh. - if (n.length === 1) { - n = "0" + n; - } - return n; - } - function dateToISO8601(date) { - // wow I hate working with the Date object - var year = date.getYear(); - var month = this.leadingZero(date.getMonth()); - var day = this.leadingZero(date.getDate()); - var time = this.leadingZero(date.getHours()) + - ":" + this.leadingZero(date.getMinutes()) + - ":" + this.leadingZero(date.getSeconds()); - - var converted = year + month + day + "T" + time; - return converted; - } - var xml = ""; xml += dateToISO8601(data); xml += ""; -- cgit From 0ccc730b8cf0f66a8e9a15cc07b5b6613fc0e015 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Sun, 17 Apr 2011 08:44:49 +0200 Subject: Auch! Say NO to the copy&paste inheritance! * leadingZero made into special function exported from xmlrpc module (it is now able to accept either number of string as its parameter) * added tests for leadingZero --- lib/logger.js | 14 +++----------- lib/xmlrpc.js | 24 ++++++++++++++++++------ tests/test-xmlrpc.js | 13 +++++++++++++ 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/lib/logger.js b/lib/logger.js index 7e0c516..d4c5dc9 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -79,21 +79,13 @@ exports.generateTimeSheet = function generateTimeSheet() { }; function timeSheetRecordsPrinter(records) { - function leadingZero(n) { - // pads a single number with a leading zero. Heh. - var s = n.toString(); - if (s.length === 1) { - s = "0" + s; - } - return s; - } - var commentBugRE = new RegExp("[bB]ug\\s+([0-9]+)","g"); // sort the records into temporary array var tmpArr = []; var today = new Date(); - var todayStr = today.getFullYear()+"-"+leadingZero(today.getMonth()+1)+ - "-"+leadingZero(today.getDate()); + var todayStr = today.getFullYear() + "-" + + xrpc.leadingZero(today.getMonth()+1) + "-" + + xrpc.leadingZero(today.getDate()); var outStr = '' + "\n"+ "\n"+ diff --git a/lib/xmlrpc.js b/lib/xmlrpc.js index 6576f31..e038c4e 100644 --- a/lib/xmlrpc.js +++ b/lib/xmlrpc.js @@ -26,15 +26,27 @@ * not an instance of SAME Array. */ -var dateToISO8601 = exports.dateToISO8601 = function dateToISO8601(date) { - function leadingZero(n) { - // pads a single number with a leading zero. Heh. - if (n.length === 1) { - n = "0" + n; - } +/** + * pads a single number with a leading zero. Heh. + * + * @param n String or Number + * @return String with leading zero added if necessary + * + * If the real parameter is not numerical, it is just returned as it is. + */ +var leadingZero = exports.leadingZero = function leadingZero(n) { + if (isNaN(Number(n))) { return n; + }; + + var s = "0" + n; + if (s.length > 2) { + s = s.slice(1); } + return s; +}; +var dateToISO8601 = exports.dateToISO8601 = function dateToISO8601(date) { // wow I hate working with the Date object console.log("date = " + date); var year = date.getYear(); diff --git a/tests/test-xmlrpc.js b/tests/test-xmlrpc.js index 677a581..f3f2e56 100644 --- a/tests/test-xmlrpc.js +++ b/tests/test-xmlrpc.js @@ -15,6 +15,19 @@ var xmlOut = "\n" + "\n1\n\n" + "\n"; +exports.ensureLeadingZero = function (test) { + test.assert(typeof(xrpc.leadingZero) == "function"); + test.assertEqual(xrpc.leadingZero("1"), "01"); + test.assertEqual(xrpc.leadingZero(1), "01"); + test.assertEqual(xrpc.leadingZero("11"), "11"); + test.assertEqual(xrpc.leadingZero(11), "11"); + test.assertEqual(xrpc.leadingZero("111"), "111"); + test.assertEqual(xrpc.leadingZero(111), "111"); + test.assertEqual(xrpc.leadingZero("-1"), "-1"); + test.assertEqual(xrpc.leadingZero(-1), "-1"); + test.assertEqual(xrpc.leadingZero("zzz"),"zzz"); +}; + // testing xrpc.XMLRPCMessage exports.ensureGenerateXMLRPC = function (test) { var msg = new xrpc.XMLRPCMessage("bugzilla.updateAttachMimeType"); -- cgit From 174bd99957fa0566aa1f4ef3e122c7dcf484392f Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Sun, 17 Apr 2011 10:03:45 +0200 Subject: Make logger.timeSheetRecordsPrinter testeable and add unit test. --- lib/logger.js | 13 ++++++------- tests/test-logger.js | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 tests/test-logger.js diff --git a/lib/logger.js b/lib/logger.js index d4c5dc9..0b18c1b 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -74,22 +74,21 @@ function getBugzillaAbbr(url) { } exports.generateTimeSheet = function generateTimeSheet() { - var docHTML = timeSheetRecordsPrinter(myStorage.storage.logs); + var docHTML = timeSheetRecordsPrinter(myStorage.storage.logs, new Date()); libbz.openURLInNewTab("data:text/html;charset=utf-8," + docHTML); }; -function timeSheetRecordsPrinter(records) { +exports.timeSheetRecordsPrinter = function timeSheetRecordsPrinter(records, date) { var commentBugRE = new RegExp("[bB]ug\\s+([0-9]+)","g"); // sort the records into temporary array var tmpArr = []; - var today = new Date(); - var todayStr = today.getFullYear() + "-" + - xrpc.leadingZero(today.getMonth()+1) + "-" + - xrpc.leadingZero(today.getDate()); + var dateStr = date.getFullYear() + "-" + + xrpc.leadingZero(date.getMonth()+1) + "-" + + xrpc.leadingZero(date.getDate()); var outStr = '' + "\n"+ "\n"+ - "TimeSheet-"+ todayStr + "\n\n\n" + + "TimeSheet-"+ dateStr + "\n\n\n" + "

TimeSheet

\n"; for (var i in records) { diff --git a/tests/test-logger.js b/tests/test-logger.js new file mode 100644 index 0000000..2b087f8 --- /dev/null +++ b/tests/test-logger.js @@ -0,0 +1,39 @@ +/*global exports: false, require: false */ +/*jslint plusplus: false */ +"use strict"; +var xrpc = require("xmlrpc"); +var logMod = require("logger"); +var selfMod = require("self"); + +var testGenerateTimeSheetDataLogs = { + "2010-07-27+bugzilla.redhat.com+533567": { + "date": "2010-07-27T21:28:47.103Z", + "url": "https://bugzilla.redhat.com/show_bug.cgi?id=533567", + "title": "KMS:RS480:X200M - GPU lockup (screen goes black)", + "comment": "removing filled in chip type for Guadec" + }, + "2010-07-27+bugzilla.redhat.com+618769": { + "date": "2010-07-27T21:30:18.845Z", + "url": "https://bugzilla.redhat.com/show_bug.cgi?id=618769", + "title": "gdm and display unstable with ATI FirePro V3700 graphics card", + "comment": "asking for logs" + } +}; +var testGenerateTimeSheetResultStr = "\n\n"+ + "TimeSheet-2011-04-17\n\n\n

TimeSheet

\n"+ + "

2010-07-27

\n

"+ + "Bug RH/533567: "+ + "KMS:RS480:X200M - GPU lockup (screen goes black) \n
removing filled "+ + "in chip type for Guadec

\n

Bug RH/618769: "+ + "gdm and display unstable with ATI FirePro V3700 graphics card \n"+ + "
asking for logs

\n"; + +exports.ensureTimeSheetRecordsPrinter = function (test) { + logMod.initialize(JSON.parse(selfMod.data.load( + "bugzillalabelAbbreviations.json"))) + test.assertEqual(logMod.timeSheetRecordsPrinter(testGenerateTimeSheetDataLogs, + new Date("2011-04-17")), testGenerateTimeSheetResultStr, + "Generates correct log report from given data."); +}; + -- cgit From f13035316562baa2716344e75a0506328d8a8ef6 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Sun, 17 Apr 2011 15:42:50 +0200 Subject: New version 0.94 ... also clean up update.rdf. --- package.json | 2 +- update.rdf | 109 +++++++++++++++++++++++++---------------------------------- 2 files changed, 47 insertions(+), 64 deletions(-) diff --git a/package.json b/package.json index e208c36..b16f406 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "description": "Additional buttons and other function helping in the triage on bugzilla", "author": "Matej Cepl (http://matej.ceplovi.cz)", "license": "MIT/X11 (http://opensource.org/licenses/mit-license.php) and MPL", - "version": "0.93", + "version": "0.94", "contributors": [ "Ehsan Akhgari (http://ehsanakhgari.org/) ", "Johnathan Nightingale (http://johnath.com) ", diff --git a/update.rdf b/update.rdf index 7d672a9..d134bf8 100644 --- a/update.rdf +++ b/update.rdf @@ -1,23 +1,19 @@ - - 0.15 - + 0.15 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.15.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -25,17 +21,14 @@ - 0.16 - + 0.16 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.16.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -43,8 +36,7 @@ - 0.17 - + 0.17 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} @@ -56,17 +48,14 @@ - 0.18 - + 0.18 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.18.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -74,17 +63,14 @@ - 0.19 - + 0.19 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.19.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -92,17 +78,14 @@ - 0.20 - + 0.20 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.20.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -110,17 +93,14 @@ - 0.21 - + 0.21 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.21.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -128,17 +108,14 @@ - 0.22 - + 0.22 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.22.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -146,17 +123,14 @@ - 0.23 - + 0.23 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.23.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -164,17 +138,14 @@ - 0.24 - + 0.24 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.24.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -182,17 +153,14 @@ - 0.25 - + 0.25 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.25.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -200,17 +168,14 @@ - 0.26 - + 0.26 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.26.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -218,17 +183,14 @@ - 0.27 - + 0.27 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 3.6 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.27.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -236,17 +198,14 @@ - 0.90 - + 0.90 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 4.* 4.1 - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.90.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -254,17 +213,14 @@ - 0.91 - + 0.91 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 4.* 4.1 - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.91.xpi - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog @@ -272,17 +228,44 @@ - 0.92 - + 0.92 {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 4.* 4.1 - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.92.xpi - + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + + + + + 0.93 + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.* + 4.1 + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.93.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + + + + + 0.94 + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.* + 4.1 + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.94.xpi + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog -- cgit From 3371681e2fd62add63543f6229d5339698460d28 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Tue, 19 Apr 2011 00:17:40 +0200 Subject: Add a comment to follow key shortcut for Next bug. --- data/lib/jumpNextBug.js | 54 +++++++++++-------------------------------------- 1 file changed, 12 insertions(+), 42 deletions(-) diff --git a/data/lib/jumpNextBug.js b/data/lib/jumpNextBug.js index 2e097a3..348c776 100644 --- a/data/lib/jumpNextBug.js +++ b/data/lib/jumpNextBug.js @@ -2,46 +2,16 @@ // http://www.opensource.org/licenses/mit-license.php "use strict"; -(function createRelationElements() { - var relation = {}; - var linkLabels = ["First", "Last", "Prev", "Next"]; - var labelToRelation = { - "First": { - rel: "start" - }, - "Last": { - rel: "last" - }, - "Prev": { - rel: "prev" - }, - "Next": { - rel: "next" - } - }; +var nextElement = {}; +var nextRE = new RegExp("Next"); - function createLinkRel (rel, href) { - var newLinkElement = document.createElement("link"); - newLinkElement.setAttribute("rel", rel); - newLinkElement.setAttribute("href", href); - document.getElementsByTagName("head")[0]. - appendChild(newLinkElement); - } - - var aNavigElements = document.querySelectorAll("#bugzilla-body .navigation a"); - Array.forEach(aNavigElements, function(elem) { - var labelText = elem.textContent.trim(); - if (isInList(labelText, linkLabels)) { - labelToRelation[labelText].href = elem.getAttribute("href"); - }; - }); - - for (var key in labelToRelation) { - if (labelToRelation.hasOwnProperty(key)) { - relation = labelToRelation[key]; - if (relation.href) { - createLinkRel(relation.rel, relation.href); - } - } - } -})(); +var aNavigElements = document.querySelectorAll("#bugzilla-body .navigation a"); +var filteredElements = Array.filter(aNavigElements, function(elem) { + return nextRE.test(elem.textContent); +}); +console.log("filteredElements.length = " + filteredElements.length); +if (filteredElements.length > 0) { + nextElement = filteredElements[0]; + nextElement.setAttribute("accesskey", "n"); + nextElement.innerHTML = "Next"; +} -- cgit From 50c6825e5d1aecca1edc75b305e28fce86e12b36 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Tue, 19 Apr 2011 00:19:53 +0200 Subject: Working on analysis of bug-page-mod module. * Add some notes * remove getBugNumber and replaced with my getBugNo. --- data/lib/bug-page-mod.js | 19 +++++++------------ data/lib/util.js | 8 ++++++-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/data/lib/bug-page-mod.js b/data/lib/bug-page-mod.js index 8972ee6..a8ce6de 100644 --- a/data/lib/bug-page-mod.js +++ b/data/lib/bug-page-mod.js @@ -46,8 +46,8 @@ function tweakBugzilla(d) { if (!d.getElementById("comments")) // don't process the mid-air collision pages return; - // Make the comment box bigger - var commentBox = d.querySelector("#comment"); + // Make the comment box bigger ... TODO not necessary on RH BZ, but doesn't hurt + var commentBox = d.getElementById("comment"); if (commentBox) commentBox.rows=20; @@ -58,6 +58,8 @@ function tweakBugzilla(d) { viewAttachmentSource(d); // Mark up history along right hand edge + // TODO ... not sure what does this mean ... this + // element is I suppose everywhere. var historyLink = d.querySelector("link[title='Bug Activity']"); if (!historyLink) return; @@ -479,7 +481,7 @@ var reviewBoardUrlBase = "http://reviews.visophyte.org/"; * review board magic. */ function attachmentDiffLinkify(doc) { - var bug_id = getBugNumber(doc); + var bug_id = getBugNo(doc); var table = doc.getElementById("attachment_table"); if (!table) @@ -696,7 +698,7 @@ function CheckinCommentCtor() { } CheckinCommentCtor.prototype = { initialize: function(doc, flags) { - this.bugNumber = getBugNumber(doc); + this.bugNumber = getBugNo(doc); var summarySpan = doc.getElementById("short_desc_nonedit_display"); if (summarySpan) { this.summary = summarySpan.textContent; @@ -819,7 +821,7 @@ function DataStoreCtor(doc) { DataStoreCtor.prototype = { initialize: function(doc) { - this.bugNumber = getBugNumber(doc); + this.bugNumber = getBugNo(doc); var data = this._ensureEntry(this.bugNumber, this.data); // last visited date data.visitedTime = (new Date()).getTime(); @@ -917,13 +919,6 @@ DataStoreCtor.prototype = { _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i }; -function getBugNumber(doc) { - var idField = doc.querySelector("form[name=changeform] input[name=id]"); - if (idField) { - return idField.value; - } - return null; -} function getUserName(doc) { var links = doc.querySelectorAll("#header .links li"); diff --git a/data/lib/util.js b/data/lib/util.js index 6256171..40a782f 100644 --- a/data/lib/util.js +++ b/data/lib/util.js @@ -64,8 +64,12 @@ function parseXMLfromString (inStuff) { * Get a bug no */ function getBugNo() { - console.log("bugNo = " + document.forms.namedItem('changeform').getElementsByName("id")[0].value); - return document.forms.namedItem('changeform').getElementsByName("id")[0].value; + var bugNoElem = document.forms.namedItem('changeform').getElementsByName("id")[0]; + if (bugNoElem) { + return bugNoElem.value; + } else { + return null; + } } /** -- cgit From 0b6ea333d13e6ae1cc4fa53e22c67246e0f95f32 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Wed, 20 Apr 2011 18:12:40 +0200 Subject: Add Cirrus GD5446 chip (emulated in KVM) to the chipNames.json. --- chip-data/chipNames.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chip-data/chipNames.json b/chip-data/chipNames.json index ed78655..3afc08f 100644 --- a/chip-data/chipNames.json +++ b/chip-data/chipNames.json @@ -557,5 +557,6 @@ "8086,0122":["Sandybridge"], "8086,0126":["Sandybridge"], "8086,010A":["Sandybridge"], - "15AD:0405":["VMware_SVGA_II"] + "15AD:0405":["VMware_SVGA_II"], + "1013:00B8":["GD5446_KVM"] } -- cgit From 197e98076352809946aabc2c8f042374f2af549e Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 21 Apr 2011 15:59:49 +0200 Subject: Add better logging support. https://bugzilla.mozilla.org/show_bug.cgi?id=582760 is still unfixed. --- data/lib/rhbzpage.js | 9 +++++++-- data/lib/util.js | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index 4adb6ea..d8f5727 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -1,6 +1,9 @@ // Released under the MIT/X11 license // http://www.opensource.org/licenses/mit-license.php +// Are we debugging? +var debugFlag = true; + // For identification of graphics card var manuChipStrs = [ [ "ATI Radeon", "ATI", "1002" ], [ "ATI Mobility Radeon", "ATI", "1002" ], @@ -131,6 +134,7 @@ function RHcentralCommandDispatch(cmdLabel, cmdParams) { markBugTriaged(); break; case "chipMagic": + console.myDebug("cmdParams = " + cmdParams.toSource()); fillInWhiteBoard(cmdParams); break; // If we don't have it here, call superclass method @@ -151,7 +155,7 @@ function RHcentralCommandDispatch(cmdLabel, cmdParams) { function markBadAttachments(atts) { var badMIMEArray = [ "application/octet-stream", "text/x-log", "undefined" ]; if (!constantData.passwordState.passAvailable) { - console.log("markBadAttachments : No password, no XML-RPC calls; sorry"); + console.myDebug("markBadAttachments : No password, no XML-RPC calls; sorry"); return null; } @@ -244,6 +248,7 @@ function fillInWhiteBoard(PCIidArrObj) { } } + console.myDebug("fillInWhiteBoard: cardName = " + cardName); clickMouse("editme_action"); var titleElem = document.getElementById('short_desc'); titleElem.value = '[' + cardName + ']\u00A0' + titleElem.value; @@ -381,7 +386,7 @@ function addClosingUpstream() { centralCommandDispatch("resolution", "UPSTREAM"); } else { - console.log("No external bug specified among the External References!"); + console.myDebug("No external bug specified among the External References!"); } } diff --git a/data/lib/util.js b/data/lib/util.js index 40a782f..fa111aa 100644 --- a/data/lib/util.js +++ b/data/lib/util.js @@ -355,3 +355,9 @@ var NotLoggedinException = function NotLoggedinException (message) { NotLoggedinException.prototype.toString = function () { return this.name + ': "' + this.message + '"'; }; + +console.myDebug = function myDebug(str) { + if (debugFlag) { + console.log(str); + } +}; -- cgit From 15c6a56eba1600ed23c29c6d769e49221fb000ce Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 21 Apr 2011 16:01:16 +0200 Subject: Fixing "Fixing Magic" for nvidia. --- data/lib/rhbzpage.js | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index d8f5727..e0c5cec 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -2,7 +2,7 @@ // http://www.opensource.org/licenses/mit-license.php // Are we debugging? -var debugFlag = true; +var debugFlag = false; // For identification of graphics card var manuChipStrs = [ [ "ATI Radeon", "ATI", "1002" ], @@ -220,9 +220,10 @@ function addCheckXorgLogLink(attList) { * * @param PCIidArrObj object with two fields * id Array manufacturer-ID and product-ID (PCI IDs) - * chipsetLine RE + * chipsetLine whole line containing PCI ID. * @param driverStr String with the driver name * @return None + * */ function fillInWhiteBoard(PCIidArrObj) { var outStr = ""; @@ -231,7 +232,13 @@ function fillInWhiteBoard(PCIidArrObj) { var cardName = ""; var PCIid = (PCIidArrObj.id[0] + "," + PCIidArrObj.id[1]).toUpperCase(); + console.myDebug("PCIidArrObj = " + PCIidArrObj.toSource()); + console.myDebug("PCIid = " + PCIid); + + // Nvidia driver provides good code in the if (PCIidArrObj.id[0].toLowerCase() == "10de") { + // The following is wrong ... chipsetLine is String, not an array + console.myDebug("fillInWhiteBoard: chipsetLine = " + PCIidArrObj.chipsetLine); cardName = PCIidArrObj.chipsetLine[2].replace(/\s*nvidia\s*/ig,""). replace('"','','g'); } @@ -267,17 +274,34 @@ function fillInChipMagic(XlogID) { analyzeXorgLog(XlogID, "AnalyzeInterestingLine"); } +/** + * Creates a button to change summary by adding a graphic chip label + * + * @param Array with matching results of re.exec() + */ function chipsetMagic (interestingLineArr) { // parse Xorg.0.log + var chipsetLine = ""; + console.myDebug("interestingLineArr = " + interestingLineArr.toSource()); + console.myDebug("interestingLineArr[1] = " + interestingLineArr[1]); if (interestingLineArr.length >0) { var interestingArray = interestingLineArr[0]; if (interestingArray.length > 1) { var interestingPCIID = interestingArray[2].trim().split(":"); + // If we have Chipset line, we should parse it as well and + // add to the button + if (interestingLineArr.length > 1) { + chipsetLine = interestingLineArr[1]; + console.myDebug("chipsetLine = " + chipsetLine.toSource()); + } else { + chipsetLine = null; + console.myDebug("chipsetLine = " + chipsetLine); + } createNewButton("short_desc_nonedit_display", false, { "name": "Fill In", "chipMagic": { "id": interestingPCIID, - "chipsetLine": interestingLineArr[1] + "chipsetLine": chipsetLine }, }); } @@ -326,15 +350,23 @@ function findInterestingLine(wholeLog, backMsg) { return new RegExp(reone); }); } + console.myDebug("Current REs:"); + REarr.forEach(function (re) { + console.myDebug("re: " + re.source); + }); + var results = []; wholeLog.split("\n"). forEach(function(line) { REarr.forEach(function (re, reIdx) { if (re.test(line)) { + console.myDebug("Found match on line:\n" + line); + console.myDebug("Result: " + re.exec(line).toSource()); results.push(re.exec(line)); } }); }); + console.myDebug("results = " + results.toSource()); logAnalyzeLogic[backMsg].func(results); } -- cgit From 9a2e436b841d7c0d9d162b1d386a4316c7feb62e Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 21 Apr 2011 16:26:10 +0200 Subject: debugFlag must be in util.js as well. --- data/lib/rhbzpage.js | 3 - data/lib/util.js | 3 + package.json | 2 +- update.rdf | 564 ++++++++++++++++++++++++++++----------------------- 4 files changed, 311 insertions(+), 261 deletions(-) diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index e0c5cec..6b8ee9f 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -1,9 +1,6 @@ // Released under the MIT/X11 license // http://www.opensource.org/licenses/mit-license.php -// Are we debugging? -var debugFlag = false; - // For identification of graphics card var manuChipStrs = [ [ "ATI Radeon", "ATI", "1002" ], [ "ATI Mobility Radeon", "ATI", "1002" ], diff --git a/data/lib/util.js b/data/lib/util.js index fa111aa..5b628cf 100644 --- a/data/lib/util.js +++ b/data/lib/util.js @@ -356,6 +356,9 @@ NotLoggedinException.prototype.toString = function () { return this.name + ': "' + this.message + '"'; }; +// Are we debugging? +var debugFlag = false; + console.myDebug = function myDebug(str) { if (debugFlag) { console.log(str); diff --git a/package.json b/package.json index b16f406..cf45cb3 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "description": "Additional buttons and other function helping in the triage on bugzilla", "author": "Matej Cepl (http://matej.ceplovi.cz)", "license": "MIT/X11 (http://opensource.org/licenses/mit-license.php) and MPL", - "version": "0.94", + "version": "0.95", "contributors": [ "Ehsan Akhgari (http://ehsanakhgari.org/) ", "Johnathan Nightingale (http://johnath.com) ", diff --git a/update.rdf b/update.rdf index d134bf8..c80bc9d 100644 --- a/update.rdf +++ b/update.rdf @@ -1,278 +1,328 @@ - - + + + - - - + +
  • + 0.15 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.15.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.15.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.16 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.16.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.16.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.17 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + + +
  • +
  • + 0.18 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.18.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.18.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.19 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.19.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.19.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.20 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.20.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.20.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.21 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.21.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.21.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.22 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.22.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.22.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.23 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.23.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.23.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.24 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.24.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.24.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.25 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.25.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.25.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.26 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.26.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.26.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.27 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 3.6 - 4.* - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.27.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 3.6 + 4.* + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.27.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.90 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 4.* - 4.1 - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.90.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.* + 4.1 + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.90.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.91 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 4.* - 4.1 - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.91.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.* + 4.1 + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.91.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.92 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 4.* - 4.1 - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.92.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.* + 4.1 + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.92.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.93 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 4.* - 4.1 - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.93.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.* + 4.1 + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.93.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + 0.94 - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 4.* - 4.1 - https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.94.xpi - - https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog - - - - - + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.* + 4.1 + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.94.xpi + + https://fedorahosted.org/bugzilla-triage-scripts/wiki/ChangeLog + + + +
  • +
  • + + 0.95 + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.0b7 + * + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.95.xpi + + + +
  • +
    -
    - -
    + + -- cgit From ca6d6953457b0176f9aed372367cb2645e575f3e Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 21 Apr 2011 23:58:00 +0200 Subject: Fix nvidia. What to do when nvidia chipset is using VESA drivers or something similar. Driver names are not 100% proxy for the card type. --- data/lib/rhbzpage.js | 75 ++++++++++++++++++++++------------------------------ data/lib/util.js | 2 +- 2 files changed, 33 insertions(+), 44 deletions(-) diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index 6b8ee9f..43d34c2 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -222,36 +222,7 @@ function addCheckXorgLogLink(attList) { * @return None * */ -function fillInWhiteBoard(PCIidArrObj) { - var outStr = ""; - var cardIDStr = ""; - var cardIDArr = []; - var cardName = ""; - var PCIid = (PCIidArrObj.id[0] + "," + PCIidArrObj.id[1]).toUpperCase(); - - console.myDebug("PCIidArrObj = " + PCIidArrObj.toSource()); - console.myDebug("PCIid = " + PCIid); - - // Nvidia driver provides good code in the - if (PCIidArrObj.id[0].toLowerCase() == "10de") { - // The following is wrong ... chipsetLine is String, not an array - console.myDebug("fillInWhiteBoard: chipsetLine = " + PCIidArrObj.chipsetLine); - cardName = PCIidArrObj.chipsetLine[2].replace(/\s*nvidia\s*/ig,""). - replace('"','','g'); - } - else { - try { - cardName = constantData.chipNames[PCIid][0]; - } catch (e if e instanceof TypeError) { - PCIid = PCIid.toLowerCase().replace(",",":"); - postMessage(new Message("SetClipboard", PCIid.toString())); - alert("PCI ID " + PCIid + " is not known!"); - return ; // early termination - } catch (e) { - throw e; - } - } - +function fillInWhiteBoard(cardName) { console.myDebug("fillInWhiteBoard: cardName = " + cardName); clickMouse("editme_action"); var titleElem = document.getElementById('short_desc'); @@ -278,9 +249,10 @@ function fillInChipMagic(XlogID) { */ function chipsetMagic (interestingLineArr) { // parse Xorg.0.log - var chipsetLine = ""; + var cardStr = ""; console.myDebug("interestingLineArr = " + interestingLineArr.toSource()); console.myDebug("interestingLineArr[1] = " + interestingLineArr[1]); + if (interestingLineArr.length >0) { var interestingArray = interestingLineArr[0]; if (interestingArray.length > 1) { @@ -288,19 +260,36 @@ function chipsetMagic (interestingLineArr) { // If we have Chipset line, we should parse it as well and // add to the button if (interestingLineArr.length > 1) { - chipsetLine = interestingLineArr[1]; - console.myDebug("chipsetLine = " + chipsetLine.toSource()); - } else { - chipsetLine = null; - console.myDebug("chipsetLine = " + chipsetLine); + var PCIid = (interestingPCIID[0] + "," + interestingPCIID[1]). + toUpperCase(); + // Nvidia driver provides good code in the Chipset line + if (interestingPCIID[0].toLowerCase() == "10de") { + cardStr = interestingLineArr[1][2]. + replace(/\s*nvidia\s*/ig,""). + replace('"','','g'); + } else { + try { + cardStr = constantData.chipNames[PCIid][0]; + } catch (e if e instanceof TypeError) { + PCIid = PCIid.toLowerCase().replace(",",":"); + cardStr = null; + alert("PCI ID " + PCIid + " is not known!"); + postMessage(new Message("SetClipboard", PCIid.toString())); + } catch (e) { + throw e; + } + } + } + else { + cardStr = null; + } + + if (cardStr) { + createNewButton("short_desc_nonedit_display", false, { + "name": "Fill In", + "chipMagic": cardStr, + }); } - createNewButton("short_desc_nonedit_display", false, { - "name": "Fill In", - "chipMagic": { - "id": interestingPCIID, - "chipsetLine": chipsetLine - }, - }); } } } diff --git a/data/lib/util.js b/data/lib/util.js index 5b628cf..b145d25 100644 --- a/data/lib/util.js +++ b/data/lib/util.js @@ -357,7 +357,7 @@ NotLoggedinException.prototype.toString = function () { }; // Are we debugging? -var debugFlag = false; +var debugFlag = true; console.myDebug = function myDebug(str) { if (debugFlag) { -- cgit From 28fca6be6eed43da9b9449257a8577e4d8597590 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 22 Apr 2011 02:20:14 +0200 Subject: Add the roll-down list for selection of categories. --- data/lib/otherButtons.js | 6 ++++- data/lib/rhbzpage.js | 4 ++++ data/lib/xorgBugCategories.js | 51 +++++++++++++++++++++++++++++++++++++++++++ lib/main.js | 1 + 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 data/lib/xorgBugCategories.js diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js index 3a1f76a..7a11395 100644 --- a/data/lib/otherButtons.js +++ b/data/lib/otherButtons.js @@ -60,7 +60,11 @@ function markBugTriaged() { // /fedora-meeting.2009-11-24-15.11.log.html // http://meetbot.fedoraproject.org/fedora-meeting/2009-11-24\ // /fedora-meeting.2009-11-24-15.11.log.html - addStuffToTextBox("keywords","Triaged"); + if (!hasXorgBugsCategory()) { + alert("This won't do! First set the category!"); + } else { + addStuffToTextBox("keywords","Triaged"); + } } function addingEmbelishments(list) { diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index 43d34c2..8071c80 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -468,6 +468,10 @@ function RHBZinit() { setDefaultAssignee(); } + if (constantData.xorgBugsCategories) { + makeBugCategoriesList(constantData.xorgBugsCategories); + } + // Dig out backtrace protection against double-firing? btSnippet = ""; diff --git a/data/lib/xorgBugCategories.js b/data/lib/xorgBugCategories.js new file mode 100644 index 0000000..f47ad1d --- /dev/null +++ b/data/lib/xorgBugCategories.js @@ -0,0 +1,51 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php +"use strict"; + +function hasXorgBugsCategory() { + var catRE = /\s*\[cat:.*?\]\s*/; // RE for testing whether + // there is already category tag in the Whiteboard + + var whiteboardContent = document. + getElementById("status_whiteboard").value; + return (catRE.test(whiteboardContent)); +} + +/** + * Create a category list to the upper toolbar + */ +function makeBugCategoriesList(catList) { + + // Create with s for each category one + catList.forEach(function (cat) { + optionElement = document.createElement("option"); + optionElement.value = cat; + optionElement.setAttribute("id", "catId_" + cat.replace(" ","").toLowerCase()); + optionElement.appendChild(document.createTextNode(cat)); + categoryList.appendChild(optionElement); + }); + + categoryList.addEventListener("change", function (evt) { + var selectedCategory = "[cat:" + this.value + "]"; + var whiteboardElement = document.getElementById("status_whiteboard"); + + if (hasXorgBugsCategory()) { + whiteboardElement.value = whiteboardElement. + value.replace(catRE, ""); + } + addStuffToTextBox("status_whiteboard", selectedCategory); + }, false); + + targetDiv.insertBefore(categoryList, targetDiv.firstChild); +} diff --git a/lib/main.js b/lib/main.js index f3de753..645669a 100644 --- a/lib/main.js +++ b/lib/main.js @@ -118,6 +118,7 @@ var contentScriptLibraries = [ self.data.url("lib/jumpNextBug.js"), self.data.url("lib/queries.js"), self.data.url("lib/preprocessDuplicates.js"), + self.data.url("lib/xorgBugCategories.js"), self.data.url("lib/viewSource.js"), self.data.url("lib/color.js"), self.data.url("lib/addNewLinks.js"), -- cgit From fea37bf96ab3b0494a44f9737061898260dc5d41 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 22 Apr 2011 02:33:46 +0200 Subject: New release 0.96. --- package.json | 2 +- update.rdf | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index cf45cb3..dfb5534 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "description": "Additional buttons and other function helping in the triage on bugzilla", "author": "Matej Cepl (http://matej.ceplovi.cz)", "license": "MIT/X11 (http://opensource.org/licenses/mit-license.php) and MPL", - "version": "0.95", + "version": "0.96", "contributors": [ "Ehsan Akhgari (http://ehsanakhgari.org/) ", "Johnathan Nightingale (http://johnath.com) ", diff --git a/update.rdf b/update.rdf index c80bc9d..ad23b9d 100644 --- a/update.rdf +++ b/update.rdf @@ -322,6 +322,21 @@ xmlns:em="http://www.mozilla.org/2004/em-rdf#"> +
  • + + 0.96 + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.0b7 + * + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.96.xpi + + + +
  • -- cgit From 738734fc32b9d0c52b89208c708fd6a6f3cc0531 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 22 Apr 2011 04:05:34 +0200 Subject: Make the categories work only for Xorg bugs. --- data/lib/otherButtons.js | 5 +++-- data/lib/rhbzpage.js | 4 +++- data/lib/util.js | 2 +- data/lib/xorgBugCategories.js | 27 +++++++++++++++++++-------- lib/main.js | 2 +- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js index 7a11395..1cca24b 100644 --- a/data/lib/otherButtons.js +++ b/data/lib/otherButtons.js @@ -67,8 +67,8 @@ function markBugTriaged() { } } -function addingEmbelishments(list) { var FillMagicDoneRE = new RegExp("^\\s*\\[[0-9a-zA-Z_]*\\]"); +function addingEmbelishments(list) { var maintCCAddr = ""; if (constantData.CCmaintainer) { @@ -142,7 +142,8 @@ function setBranding(xLogAtts) { brandColor = RHColor; } } - else if (new RegExp("Fedora").test(document.getElementById("product").value)) { + else if (new RegExp("Fedora").test(document. + getElementById("product").value)) { if (document.getElementById("version").value === "rawhide") { brandColor = RawhideColor; } diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index 8071c80..bce5ac1 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -469,7 +469,9 @@ function RHBZinit() { } if (constantData.xorgBugsCategories) { - makeBugCategoriesList(constantData.xorgBugsCategories); + var XBZlist = filterByRegexp(constantData. + xorgBugsCategories, getComponent()); + makeBugCategoriesList(XBZlist); } // Dig out backtrace protection against double-firing? diff --git a/data/lib/util.js b/data/lib/util.js index b145d25..c2989d2 100644 --- a/data/lib/util.js +++ b/data/lib/util.js @@ -284,7 +284,7 @@ function filterByRegexp(list, chosingMark) { return chosenPair[0].addr; } else { - return ""; + return null; } } diff --git a/data/lib/xorgBugCategories.js b/data/lib/xorgBugCategories.js index f47ad1d..8168f18 100644 --- a/data/lib/xorgBugCategories.js +++ b/data/lib/xorgBugCategories.js @@ -6,15 +6,23 @@ function hasXorgBugsCategory() { var catRE = /\s*\[cat:.*?\]\s*/; // RE for testing whether // there is already category tag in the Whiteboard + var isXOrgBug = filterByRegexp(constantData. + xorgBugsCategories, getComponent()); + console.myDebug("isXOrgBug = " + isXOrgBug); var whiteboardContent = document. getElementById("status_whiteboard").value; - return (catRE.test(whiteboardContent)); + console.myDebug("whiteboardContent = " + whiteboardContent); + console.myDebug("catRE.test = " + catRE.test(whiteboardContent)); + + return (isXOrgBug && catRE.test(whiteboardContent)); } /** * Create a category list to the upper toolbar */ function makeBugCategoriesList(catList) { + var catRE = /\s*\[cat:.*?\]\s*/; // RE for testing whether + // there is already category tag in the Whiteboard // Create with s for each category one - catList.forEach(function (cat) { - optionElement = document.createElement("option"); - optionElement.value = cat; - optionElement.setAttribute("id", "catId_" + cat.replace(" ","").toLowerCase()); - optionElement.appendChild(document.createTextNode(cat)); - categoryList.appendChild(optionElement); - }); + if (catList) { + catList.forEach(function (cat) { + optionElement = document.createElement("option"); + optionElement.value = cat; + optionElement.setAttribute("id", "catId_" + + cat.replace(" ","").toLowerCase()); + optionElement.appendChild(document.createTextNode(cat)); + categoryList.appendChild(optionElement); + }); + } categoryList.addEventListener("change", function (evt) { var selectedCategory = "[cat:" + this.value + "]"; diff --git a/lib/main.js b/lib/main.js index 645669a..849da68 100644 --- a/lib/main.js +++ b/lib/main.js @@ -118,11 +118,11 @@ var contentScriptLibraries = [ self.data.url("lib/jumpNextBug.js"), self.data.url("lib/queries.js"), self.data.url("lib/preprocessDuplicates.js"), - self.data.url("lib/xorgBugCategories.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/xorgBugCategories.js"), self.data.url("lib/otherButtons.js"), self.data.url("lib/makeBacktraceAttachment.js"), self.data.url("lib/fixingAttMIME.js"), -- cgit From fe02d1337e9f4377b381f311efb8224a50ef8903 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 22 Apr 2011 04:12:39 +0200 Subject: New release 0.97. --- package.json | 2 +- update.rdf | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index dfb5534..30e793d 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "description": "Additional buttons and other function helping in the triage on bugzilla", "author": "Matej Cepl (http://matej.ceplovi.cz)", "license": "MIT/X11 (http://opensource.org/licenses/mit-license.php) and MPL", - "version": "0.96", + "version": "0.97", "contributors": [ "Ehsan Akhgari (http://ehsanakhgari.org/) ", "Johnathan Nightingale (http://johnath.com) ", diff --git a/update.rdf b/update.rdf index ad23b9d..bbe1641 100644 --- a/update.rdf +++ b/update.rdf @@ -337,6 +337,21 @@ xmlns:em="http://www.mozilla.org/2004/em-rdf#"> +
  • + + 0.96 + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.0b7 + * + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.97.xpi + + + +
  • -- cgit From 2a04c3fc60e4f9cd8b59cbe6bcfbd56d0e29c98f Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 22 Apr 2011 04:57:30 +0200 Subject: Fixed other functions broken * not all functions are able to accept the null as return value (directly or indirectly) of filterByRegexp * finally make all logic not to affect components which shouldn't be bothered with the test. --- data/lib/bugzillaDOMFunctions.js | 3 +-- data/lib/otherButtons.js | 4 ++-- data/lib/queries.js | 3 +++ data/lib/rhbzpage.js | 4 +++- data/lib/xorgBugCategories.js | 18 ++++++++++++++---- update.rdf | 2 +- 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/data/lib/bugzillaDOMFunctions.js b/data/lib/bugzillaDOMFunctions.js index 30405f0..0f22020 100644 --- a/data/lib/bugzillaDOMFunctions.js +++ b/data/lib/bugzillaDOMFunctions.js @@ -133,8 +133,7 @@ function getOwner () { * @return String with the maintainer's email address */ function getDefaultBugzillaMaintainer (component) { - var address = filterByRegexp(constantData.defBugzillaMaintainerArr, component); - return address; + return filterByRegexp(constantData.defBugzillaMaintainerArr, component); } /** diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js index 1cca24b..2f93ea7 100644 --- a/data/lib/otherButtons.js +++ b/data/lib/otherButtons.js @@ -33,7 +33,7 @@ function collectComments () { */ function getDefaultAssignee() { return filterByRegexp(constantData.defaultAssignee, - getComponent()).toLowerCase(); + getComponent()); } /** @@ -46,7 +46,7 @@ function setDefaultAssignee() { var defAss = getDefaultAssignee(); // Add setting default assignee - if ((defAss.length > 0) && (defAss !== getOwner())) { + if (defAss && (defAss !== getOwner())) { createNewButton("bz_assignee_edit_container",true, { "name": "Def. Assignee", "assignee": "default" diff --git a/data/lib/queries.js b/data/lib/queries.js index 0c00792..7f935c8 100644 --- a/data/lib/queries.js +++ b/data/lib/queries.js @@ -78,6 +78,9 @@ function queryForSelection() { */ function queryUpstreamCallback(text, queryUpBug) { var searchData = filterByRegexp(queryUpBug, getComponent()); + if (!searchData) { + return ; // not sure why it should happen, but certainly better + } var urlBase = searchData.url; text = searchData.searchBy+":"+searchData.fillIn+" "+text.trim(); if (searchData.fillIn == "$$$") { diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index bce5ac1..22e3178 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -471,7 +471,9 @@ function RHBZinit() { if (constantData.xorgBugsCategories) { var XBZlist = filterByRegexp(constantData. xorgBugsCategories, getComponent()); - makeBugCategoriesList(XBZlist); + if (XBZlist) { + makeBugCategoriesList(XBZlist); + } } // Dig out backtrace protection against double-firing? diff --git a/data/lib/xorgBugCategories.js b/data/lib/xorgBugCategories.js index 8168f18..c2c9c9b 100644 --- a/data/lib/xorgBugCategories.js +++ b/data/lib/xorgBugCategories.js @@ -2,19 +2,29 @@ // http://www.opensource.org/licenses/mit-license.php "use strict"; +/** + * Returns true if the bug is in a good shape + * + * @return Boolean if the bug is either not in the category + * where we care about it (i.e., we don't have set up categories for + * this component) or if it is in the concerned categories, then it has + * a category recorded in the whiteboard input box. + * + */ function hasXorgBugsCategory() { var catRE = /\s*\[cat:.*?\]\s*/; // RE for testing whether // there is already category tag in the Whiteboard var isXOrgBug = filterByRegexp(constantData. xorgBugsCategories, getComponent()); - console.myDebug("isXOrgBug = " + isXOrgBug); var whiteboardContent = document. getElementById("status_whiteboard").value; - console.myDebug("whiteboardContent = " + whiteboardContent); - console.myDebug("catRE.test = " + catRE.test(whiteboardContent)); - return (isXOrgBug && catRE.test(whiteboardContent)); + if (isXOrgBug) { // is it XOR? + return catRE.test(whiteboardContent); + } else { + return true; + } } /** diff --git a/update.rdf b/update.rdf index bbe1641..b3e1ee9 100644 --- a/update.rdf +++ b/update.rdf @@ -339,7 +339,7 @@ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
  • - 0.96 + 0.97 -- cgit From 6b739e89d0fa88899d680d09bbc7bcbd2628de31 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Sun, 24 Apr 2011 23:43:49 +0200 Subject: Don't allow marking bug as triaged when it doesn't have severity set. --- data/lib/bugzillaDOMFunctions.js | 9 +++++++++ data/lib/otherButtons.js | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/data/lib/bugzillaDOMFunctions.js b/data/lib/bugzillaDOMFunctions.js index 0f22020..8392b87 100644 --- a/data/lib/bugzillaDOMFunctions.js +++ b/data/lib/bugzillaDOMFunctions.js @@ -202,6 +202,15 @@ function getSummary() { return document.getElementById("short_desc_nonedit_display").textContent; } +/** + * Get the current title of the bug + * + * @return string + */ +function getSeverity() { + return document.getElementById("bug_severity").value; +} + /** * Get the current email of the reporter of the bug. * diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js index 2f93ea7..7bd36f3 100644 --- a/data/lib/otherButtons.js +++ b/data/lib/otherButtons.js @@ -62,12 +62,17 @@ function markBugTriaged() { // /fedora-meeting.2009-11-24-15.11.log.html if (!hasXorgBugsCategory()) { alert("This won't do! First set the category!"); - } else { + } + else if (getSeverity() == 'unspecified') { + alert("This won't do! Specify some severity!"); + } + else { addStuffToTextBox("keywords","Triaged"); } } - var FillMagicDoneRE = new RegExp("^\\s*\\[[0-9a-zA-Z_]*\\]"); +var FillMagicDoneRE = new RegExp("^\\s*\\[[0-9a-zA-Z_]*\\]"); + function addingEmbelishments(list) { var maintCCAddr = ""; -- cgit From ea75583841912d7204a15103a7f4555bb91fb401 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Tue, 26 Apr 2011 19:41:01 +0200 Subject: Setup logging of submits only when asked for. Fixes #86 --- data/lib/logging-front.js | 4 ---- data/lib/rhbzpage.js | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/data/lib/logging-front.js b/data/lib/logging-front.js index d186d7f..8d383e8 100644 --- a/data/lib/logging-front.js +++ b/data/lib/logging-front.js @@ -82,7 +82,3 @@ function setUpLogging () { } */ } - -if (window.location.hostname == "bugzilla.redhat.com") { - setUpLogging(); -} diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index 22e3178..a61eedf 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -476,6 +476,11 @@ function RHBZinit() { } } + // setup logging only when we ask for it + if (config.submitsLogging && (window.location.hostname == "bugzilla.redhat.com")) { + setUpLogging(); + } + // Dig out backtrace protection against double-firing? btSnippet = ""; -- cgit From 2b19aaeb2f2af979920bc9f2dd4d8df180f25c5c Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Tue, 26 Apr 2011 23:54:37 +0200 Subject: We were missing many attributes from configData. --- lib/libbugzilla.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/libbugzilla.js b/lib/libbugzilla.js index 613dbb3..7e2398b 100644 --- a/lib/libbugzilla.js +++ b/lib/libbugzilla.js @@ -19,6 +19,10 @@ var JSONURLDefault = "https://fedorahosted.org/released"+ "/bugzilla-triage-scripts/Config_data.json"; var BTSPrefNS = "bugzilla-triage.setting."; var BTSPassRealm = "BTSXMLRPCPass"; +var copiedAttributes = [ "queryButton", "upstreamButton", "parseAbrtBacktraces", + "submitsLogging", "XorgLogAnalysis", "objectStyle", "signature", + "suspiciousComponents" ]; + var passwords = {}; // hash of passwords indexed by a hostname var config = exports.config = {}; @@ -167,6 +171,7 @@ exports.getInstalledPackages = function getInstalledPackages(locationLoginObj, c } } + var allIdx = null; if ((allIdx = enabledPackages.indexOf("all")) != -1) { enabledPackages = enabledPackages.splice(allIdx, @@ -377,15 +382,11 @@ exports.initialize = function initialize(config, callback) { config.configData.defBugzillaMaintainerArr = config.constantData.CCmaintainer; } - if ("suspiciousComponents" in config.gJSONData.configData) { - config.configData.suspiciousComponents = - config.gJSONData.configData.suspiciousComponents; - } - - if ("XorgLogAnalysis" in config.gJSONData.configData) { - config.configData.xorglogAnalysis = - config.gJSONData.configData.XorgLogAnalysis; - } + copiedAttributes.forEach(function (attrib) { + if (attrib in config.gJSONData.configData) { + config.configData[attrib] = config.gJSONData.configData[attrib]; + } + }); if ("submitsLogging" in config.gJSONData.configData && config.gJSONData.configData.submitsLogging) { -- cgit From 6e4c23688bdde161f841e1bf307ed78a113f6214 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Tue, 26 Apr 2011 23:57:45 +0200 Subject: New release version 0.98 --- package.json | 2 +- update.rdf | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 30e793d..28ecc69 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "description": "Additional buttons and other function helping in the triage on bugzilla", "author": "Matej Cepl (http://matej.ceplovi.cz)", "license": "MIT/X11 (http://opensource.org/licenses/mit-license.php) and MPL", - "version": "0.97", + "version": "0.98", "contributors": [ "Ehsan Akhgari (http://ehsanakhgari.org/) ", "Johnathan Nightingale (http://johnath.com) ", diff --git a/update.rdf b/update.rdf index b3e1ee9..8938170 100644 --- a/update.rdf +++ b/update.rdf @@ -352,6 +352,21 @@ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
  • +
  • + + 0.98 + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.0b7 + * + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.98.xpi + + + +
  • -- cgit From 680ad8225d72703dcdc98a128c7dd4f408a3018b Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Wed, 27 Apr 2011 08:30:20 +0200 Subject: We don't set severity for RHEL bugs --- data/lib/otherButtons.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js index 7bd36f3..66b5a9b 100644 --- a/data/lib/otherButtons.js +++ b/data/lib/otherButtons.js @@ -63,7 +63,7 @@ function markBugTriaged() { if (!hasXorgBugsCategory()) { alert("This won't do! First set the category!"); } - else if (getSeverity() == 'unspecified') { + else if (!isEnterprise() && (getSeverity() == 'unspecified')) { alert("This won't do! Specify some severity!"); } else { -- cgit From cb82da27fc37ebe74aa9678506e72eb1a7308ca3 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 28 Apr 2011 00:39:52 +0200 Subject: Use self.on and self.postMessage instead of global on and postMessage. The reason is https://bugzilla.mozilla.org/show_bug.cgi?id=635748 and effort to save the world from global variables in content scripts. --- data/lib/addAttachmentRow.js | 2 +- data/lib/bzpage.js | 4 ++-- data/lib/cc-context.js | 4 ++-- data/lib/checkin-context.js | 6 +++--- data/lib/fixingAttMIME.js | 2 +- data/lib/logging-front.js | 8 ++++---- data/lib/makeBacktraceAttachment.js | 2 +- data/lib/queries.js | 8 ++++---- data/lib/rhbzpage.js | 8 ++++---- data/lib/util.js | 4 ++-- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/data/lib/addAttachmentRow.js b/data/lib/addAttachmentRow.js index 13ad226..204192e 100644 --- a/data/lib/addAttachmentRow.js +++ b/data/lib/addAttachmentRow.js @@ -30,7 +30,7 @@ function addAttachment(data, callback, param) { nomail: true }); - postMessage(new Message("MakeXMLRPCall", { + self.postMessage(new Message("MakeXMLRPCall", { url: constantData.XMLRPCData[window.location.hostname].url, login: getLogin(), method: "bugzilla.addAttachment", diff --git a/data/lib/bzpage.js b/data/lib/bzpage.js index f99d60c..3a832ea 100644 --- a/data/lib/bzpage.js +++ b/data/lib/bzpage.js @@ -318,7 +318,7 @@ function setConfigurationButton () { document.getElementById("configurationButton").addEventListener( "click", function(evt) { - postMessage(new Message("ChangeJSONURL", null)); + self.postMessage(new Message("ChangeJSONURL", null)); evt.stopPropagation(); evt.preventDefault(); }, false); @@ -423,7 +423,7 @@ function startup() { checkComments(); - postMessage(new Message("GetInstalledPackages", { + self.postMessage(new Message("GetInstalledPackages", { location: window.location.href, login: getLogin() })); diff --git a/data/lib/cc-context.js b/data/lib/cc-context.js index 38397a9..81b0a2d 100644 --- a/data/lib/cc-context.js +++ b/data/lib/cc-context.js @@ -1,8 +1,8 @@ -on('click', function(node, data) { +self.on('click', function(node, data) { var style = document.getElementById("bztw_cc"); style.disabled = !style.disabled; }); -on('context', function(node) { +self.on('context', function(node) { return onBugzillaPage(document.URL); }); diff --git a/data/lib/checkin-context.js b/data/lib/checkin-context.js index 4d073be..8ae482d 100644 --- a/data/lib/checkin-context.js +++ b/data/lib/checkin-context.js @@ -1,9 +1,9 @@ -on('click', function(node, data) { +self.on('click', function(node, data) { var message = document.getElementById("__bz_tw_checkin_comment"); - postMessage(message.textContent); + self.postMessage(message.textContent); }); -on('context', function(node) { +self.on('context', function(node) { if (!onBugzillaPage(document.URL)) return false; var message = document.getElementById("__bz_tw_checkin_comment"); diff --git a/data/lib/fixingAttMIME.js b/data/lib/fixingAttMIME.js index 99c32f7..a016fe6 100644 --- a/data/lib/fixingAttMIME.js +++ b/data/lib/fixingAttMIME.js @@ -62,7 +62,7 @@ function fixAttachById(id, XMLRPCURL, type, email) { 'nomail' : !email }); - postMessage(new Message("MakeXMLRPCall", { + self.postMessage(new Message("MakeXMLRPCall", { url: XMLRPCURL, login: getLogin(), method: "bugzilla.updateAttachMimeType", diff --git a/data/lib/logging-front.js b/data/lib/logging-front.js index 8d383e8..b8343a4 100644 --- a/data/lib/logging-front.js +++ b/data/lib/logging-front.js @@ -24,7 +24,7 @@ function addLogRecord() { var bugNo = getBugNoFromURL(window.location.href); rec.key = dateStr + "+" + urlStr + "+" + bugNo; - postMessage(new Message("AddLogRecord", rec)); + self.postMessage(new Message("AddLogRecord", rec)); } return rec; } @@ -57,17 +57,17 @@ function setUpLogging () { // (id, text, parent, callback, params, before, covered, accesskey) createDeadLink("generateTSButton", "Generate TS", additionalButtons, function(evt) { - postMessage(new Message("GenerateTS")); + self.postMessage(new Message("GenerateTS")); }, [], "dash", "li"); createDeadLink("clearLogs", "Clear TS", additionalButtons, function(evt) { - postMessage(new Message("ClearTS")); + self.postMessage(new Message("ClearTS")); }, [], "dash", "li"); createDeadLink("importTSButton", "Import TS", additionalButtons, function(evt) { - postMessage(new Message("ImportTS")); + self.postMessage(new Message("ImportTS")); }, [], "dash", "li"); /* TODO diff --git a/data/lib/makeBacktraceAttachment.js b/data/lib/makeBacktraceAttachment.js index e938b11..a6b6ab0 100644 --- a/data/lib/makeBacktraceAttachment.js +++ b/data/lib/makeBacktraceAttachment.js @@ -78,7 +78,7 @@ function pasteBacktraceInComments(atts) { * @return none */ function showAttachment(id) { - postMessage(new Message("OpenURLinPanel", + self.postMessage(new Message("OpenURLinPanel", "https://" + window.location.hostname + "/attachment.cgi?id=" + id)); } diff --git a/data/lib/queries.js b/data/lib/queries.js index 7f935c8..4bf959a 100644 --- a/data/lib/queries.js +++ b/data/lib/queries.js @@ -51,7 +51,7 @@ function queryInNewTab(text, component, product, equivComps) { + "&field0-0-2=status_whiteboard&type0-0-2=substring&value0-0-2=" + text; urlStr += searchText; - postMessage(new Message("OpenURLinTab", urlStr)); // utils.js is always avaiulable + self.postMessage(new Message("OpenURLinTab", urlStr)); // utils.js is always avaiulable } } @@ -62,7 +62,7 @@ function queryInNewTab(text, component, product, equivComps) { function queryForSelection() { var text = getSelection(); if (!text) { - postMessage(new Message("GetClipboard", "queryLocal")); + self.postMessage(new Message("GetClipboard", "queryLocal")); } else { if (equivalentComponents) { queryInNewTab(text, getComponent(), getProduct(), equivalentComponents); @@ -87,7 +87,7 @@ function queryUpstreamCallback(text, queryUpBug) { text = text.replace("$$$", getComponent()); } text = encodeURIComponent(text).replace("%20","+"); - postMessage(new Message("OpenURLinTab", urlBase + text)); + self.postMessage(new Message("OpenURLinTab", urlBase + text)); } /** @@ -102,7 +102,7 @@ function queryUpstream(qUpBug) { } var text = getSelection(); if (!text) { - postMessage(new Message("GetClipboard", "queryUpstream")); + self.postMessage(new Message("GetClipboard", "queryUpstream")); } else { queryUpstreamCallback(text, qUpBug); diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js index a61eedf..69317ff 100644 --- a/data/lib/rhbzpage.js +++ b/data/lib/rhbzpage.js @@ -187,7 +187,7 @@ function sendBugUpstream() { return null; } - postMessage(new Message("OpenBugUpstream", { + self.postMessage(new Message("OpenBugUpstream", { url: urlStr, subject: document.getElementById("short_desc_nonedit_display"). textContent.trim(), @@ -274,7 +274,7 @@ function chipsetMagic (interestingLineArr) { PCIid = PCIid.toLowerCase().replace(",",":"); cardStr = null; alert("PCI ID " + PCIid + " is not known!"); - postMessage(new Message("SetClipboard", PCIid.toString())); + self.postMessage(new Message("SetClipboard", PCIid.toString())); } catch (e) { throw e; } @@ -311,7 +311,7 @@ function analyzeXorg(results) { innerString += "No matching lines found!"; } - postMessage(new Message("OpenStringInPanel", + self.postMessage(new Message("OpenStringInPanel", '' + "Xorg.0.log analysis
    \n" +
         innerString.trim() +
    @@ -319,7 +319,7 @@ function analyzeXorg(results) {
     }
     
     function analyzeXorgLog(attachID, backMsg) {
    -  postMessage(new Message("GetURL", {
    +  self.postMessage(new Message("GetURL", {
         url: "https://" + window.location.hostname + "/attachment.cgi?id=" + attachID,
         backMessage: backMsg
       }));
    diff --git a/data/lib/util.js b/data/lib/util.js
    index c2989d2..4a46403 100644
    --- a/data/lib/util.js
    +++ b/data/lib/util.js
    @@ -333,7 +333,7 @@ function removeDuplicates (arr) {
     // ============================================
     /**
      * object to pack messaging. Use as in
    -    postMessage(new Message("GetPassword", {
    +    self.postMessage(new Message("GetPassword", {
           login: login,
           hostname: location.hostname
         }));
    @@ -344,7 +344,7 @@ function Message(cmd, data) {
     }
     
     function log(msg) {
    -	postMessage(new Message("LogMessage", msg));
    +	self.postMessage(new Message("LogMessage", msg));
     }
     
     var NotLoggedinException = function NotLoggedinException (message) {
    -- 
    cgit 
    
    
    From 68de408908a2cec9b0df1f67fe91939747e774e7 Mon Sep 17 00:00:00 2001
    From: Matěj Cepl 
    Date: Thu, 28 Apr 2011 01:00:35 +0200
    Subject: Two small typos
    
     * it is config.XorgLogAnalysis not lowercase one
     * timeSheetRecordsPrinter needs to be declared, otherwise it is not
       available inside of the logger.js module itself.
    ---
     data/lib/rhbzpage.js | 2 +-
     lib/logger.js        | 3 ++-
     2 files changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js
    index 69317ff..5daeea7 100644
    --- a/data/lib/rhbzpage.js
    +++ b/data/lib/rhbzpage.js
    @@ -201,7 +201,7 @@ function sendBugUpstream() {
      * @return none
      */
     function addCheckXorgLogLink(attList) {
    -  if (config.xorglogAnalysis) {
    +  if (config.XorgLogAnalysis) {
         attList.forEach(function (row) {
           var elemS = row[4].getElementsByTagName("td");
           var elem = elemS[elemS.length - 1];
    diff --git a/lib/logger.js b/lib/logger.js
    index 0b18c1b..dce3bad 100644
    --- a/lib/logger.js
    +++ b/lib/logger.js
    @@ -78,7 +78,8 @@ exports.generateTimeSheet = function generateTimeSheet() {
       libbz.openURLInNewTab("data:text/html;charset=utf-8," + docHTML);
     }; 
     
    -exports.timeSheetRecordsPrinter = function timeSheetRecordsPrinter(records, date) {
    +var timeSheetRecordsPrinter = exports.timeSheetRecordsPrinter =
    +    function timeSheetRecordsPrinter(records, date) {
       var commentBugRE = new RegExp("[bB]ug\\s+([0-9]+)","g");
       // sort the records into temporary array
       var tmpArr = [];
    -- 
    cgit 
    
    
    From f56ec76008627bb5cb139124f90101bbb83af06d Mon Sep 17 00:00:00 2001
    From: Matěj Cepl 
    Date: Thu, 28 Apr 2011 01:12:22 +0200
    Subject: Allow working with the log record without a comment.
    
    Fixes #71
    ---
     lib/logger.js | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/lib/logger.js b/lib/logger.js
    index dce3bad..ce96f69 100644
    --- a/lib/logger.js
    +++ b/lib/logger.js
    @@ -24,8 +24,8 @@ exports.initialize = function initialize(aMap) {
     };
     
     exports.addLogRecord = function addLogRecord(rec) {
    -  if (myStorage.storage.logs[rec.key]) {
    -    myStorage.storage.logs[rec.key].comment += "
    \n" + comment; + if (myStorage.storage.logs[rec.key] && myStorage.storage.logs[rec.key].comment) { + myStorage.storage.logs[rec.key].comment += "
    \n" + rec.comment; } else { myStorage.storage.logs[rec.key] = rec; -- cgit From 34bbe8e7306a0d0ec014db7512788ed92c625d19 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 28 Apr 2011 18:22:02 +0200 Subject: A bit of analysis of bugzilla-tweak script --- data/lib/bug-page-mod.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/data/lib/bug-page-mod.js b/data/lib/bug-page-mod.js index a8ce6de..192900c 100644 --- a/data/lib/bug-page-mod.js +++ b/data/lib/bug-page-mod.js @@ -120,6 +120,8 @@ function tweakBugzilla(d) { flags[name] = flagRows[i]; } var flagCounter = 1; + + // ================================================= function findFlag(item) { function lookup(names) { names = names.split(", "); @@ -328,6 +330,8 @@ function tweakBugzilla(d) { tbplbotSpamCollapser(d); } +// =================================================== + var TransformValues = { linkifyURLs: function (str) { return str.replace(/((https?|ftp)\:\/\/[\S]+)/g, '$1'); @@ -376,6 +380,8 @@ var TransformValues = { } }; +// =============================================================================== + function transform(str, type, doc, histDoc) { for (var funcname in TransformValues) { var func = TransformValues[funcname]; @@ -420,6 +426,8 @@ var TransformTypes = { } }; +// ======================================================================= + function transformType(str, doc, old, new_) { for (var funcname in TransformTypes) { var func = TransformTypes[funcname]; @@ -453,6 +461,8 @@ function formatTransition(old, new_, type, doc, histDoc) { return old + mid + new_; } +// ========================================================================= + function trimContent(el) { return el.textContent.trim(); } @@ -476,6 +486,8 @@ AttachmentFlag.prototype = { var reAttachmentDiff = /attachment\.cgi\?id=(\d+)&action=diff$/i; var reviewBoardUrlBase = "http://reviews.visophyte.org/"; +// =============================================================================== + /** * Whenever we find a patch with a diff, insert an additional link to asuth's * review board magic. -- cgit From 55d9a312fbba91f1bcf5e3f3291b7bece8abb178 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 28 Apr 2011 13:28:55 +0200 Subject: Reformatting to MoFo coding style --- data/lib/addAttachmentRow.js | 32 ++--- data/lib/addNewLinks.js | 35 +++--- data/lib/bug-page-mod.js | 12 +- data/lib/bugzillaDOMFunctions.js | 122 ++++++++++-------- data/lib/bzpage.js | 74 ++++++----- data/lib/checkin-context.js | 6 +- data/lib/color.js | 60 ++++++--- data/lib/fixingAttMIME.js | 51 ++++---- data/lib/jumpNextBug.js | 61 +++++++-- data/lib/logging-front.js | 66 +++++----- data/lib/makeBacktraceAttachment.js | 153 ++++++++++++----------- data/lib/otherButtons.js | 79 ++++++------ data/lib/preprocessDuplicates.js | 168 +++++++++++++------------ data/lib/queries.js | 122 +++++++++--------- data/lib/rhbzpage.js | 65 +++++----- data/lib/skip-bug.js | 8 +- data/lib/urltest.js | 5 +- data/lib/util.js | 149 ++++++++++++---------- data/lib/viewSource.js | 52 ++++---- data/lib/xorgBugCategories.js | 38 +++--- lib/cookiemanager.js | 4 +- lib/libbugzilla.js | 40 +++--- lib/logger.js | 82 ++++++------ lib/main.js | 135 ++++++++++---------- lib/prompts.js | 31 ++--- lib/util.js | 31 +++-- lib/xmlrpc.js | 83 +++++++------ tests/pagemod-test-helpers.js | 12 +- tests/test-color.js | 20 +-- tests/test-logger.js | 52 ++++---- tests/test-match-pattern.js | 20 +-- tests/test-pageMod.js | 195 ++++++++++++++--------------- tests/test-util.js | 240 ++++++++++++++++++++---------------- tests/test-xmlrpc.js | 39 +++--- 34 files changed, 1274 insertions(+), 1068 deletions(-) diff --git a/data/lib/addAttachmentRow.js b/data/lib/addAttachmentRow.js index 204192e..a2b67ee 100644 --- a/data/lib/addAttachmentRow.js +++ b/data/lib/addAttachmentRow.js @@ -3,39 +3,41 @@ "use strict"; function addAttachmentCallback(resp) { - var newAttachID = parseInt(resp.params.param.value.array.data.value.int, 10); + 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. + * + * 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"); + 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 + description : titleParsedAttachment, + filename : "parsed-backtrace.txt", + contenttype : "text/plain", + data : window.btoa(data), + nomail : true }); self.postMessage(new Message("MakeXMLRPCall", { - url: constantData.XMLRPCData[window.location.hostname].url, - login: getLogin(), - method: "bugzilla.addAttachment", - params: params, - callRPC: "AddAttachmentCallback" + url : constantData.XMLRPCData[window.location.hostname].url, + login : getLogin(), + method : "bugzilla.addAttachment", + params : params, + callRPC : "AddAttachmentCallback" })); reqCounter++; } diff --git a/data/lib/addNewLinks.js b/data/lib/addNewLinks.js index 02bd658..b8e7bd2 100644 --- a/data/lib/addNewLinks.js +++ b/data/lib/addNewLinks.js @@ -36,35 +36,42 @@ * ***** END LICENSE BLOCK ***** */ function addNewLinks(d) { - var product = d.querySelector("#field_container_product option[selected]"); + var product = d + .querySelector("#field_container_product option[selected]"); var component = d.querySelector("#component option[selected]"); if (product) { var label = d.getElementById('field_container_product'); - var url = 'enter_bug.cgi?product=' + encodeURIComponent(product.value); + var url = 'enter_bug.cgi?product=' + + encodeURIComponent(product.value); if (label) { - createDeadLink("file_new_bug_product", "new", label, - url, [], "parens"); + createDeadLink("file_new_bug_product", "new", label, url, + [], "parens"); } } if (product && component) { var select = d.querySelector("select#component"); var label = select.parentNode; - var url = 'enter_bug.cgi?product=' + encodeURIComponent(product.value) + - '&component=' + encodeURIComponent(component.value); + var url = 'enter_bug.cgi?product=' + + encodeURIComponent(product.value) + '&component=' + + encodeURIComponent(component.value); if (label) { - var componentElement = document.getElementById("bz_component_input"); + var componentElement = document + .getElementById("bz_component_input"); if (componentElement) { // We are in the Red Hat bugzilla - // do we have components list visible? - if (document.getElementById('bz_component_input'). - classList.contains("bz_default_hidden")) { - label = document.getElementById("bz_component_edit_container"); - } - } else { + // do we have components list visible? + if (document.getElementById('bz_component_input').classList + .contains("bz_default_hidden")) { + label = document + .getElementById("bz_component_edit_container"); + } + } + else { label = document.getElementById('component').parentNode; } - createDeadLink("file_new_bug_component", "new", label, url, [], "parens"); + createDeadLink("file_new_bug_component", "new", label, + url, [], "parens"); } } } diff --git a/data/lib/bug-page-mod.js b/data/lib/bug-page-mod.js index 192900c..a7fb7e7 100644 --- a/data/lib/bug-page-mod.js +++ b/data/lib/bug-page-mod.js @@ -43,7 +43,8 @@ function tweakBugzilla(d) { // Put the quicksearch text in the quicksearch boxes quicksearchHandler(d); - if (!d.getElementById("comments")) // don't process the mid-air collision pages + if (!d.getElementById("comments")) // don't process the mid-air collision + // pages return; // Make the comment box bigger ... TODO not necessary on RH BZ, but doesn't hurt @@ -270,7 +271,8 @@ function tweakBugzilla(d) { item = historyItems[++i].querySelectorAll("td") ccPrefix = (trimContent(item[0]) == 'CC') ? '' : ''; - // avoid showing a trailing semicolon if the previous entry wasn't a CC and this one is + // avoid showing a trailing semicolon if the previous entry + // wasn't a CC and this one is var prefix = ccSuffix + ccPrefix; // check to see if this is a flag setting flagsFound = findFlag(item); @@ -601,7 +603,8 @@ AttachmentFlagHandlerCtor.prototype = { } } - // try to put the flag name and type part in a span which we will + // try to put the flag name and type part in a span + // which we will // use in setupLinks to inject links into. match = this._reLinkifyInterestingFlag.exec(previousText); if (match) { @@ -636,7 +639,8 @@ AttachmentFlagHandlerCtor.prototype = { if (!(id in this._db)) { this._db[id] = []; } - name = name.split('@')[0]; // convert the name to the fraction before the @ + name = name.split('@')[0]; // convert the name to the fraction + // before the @ var added = this._parseData(name, trimContent(item[base + 2])); for (var i = 0; i < added.length; ++i) { var flag = added[i]; diff --git a/data/lib/bugzillaDOMFunctions.js b/data/lib/bugzillaDOMFunctions.js index 8392b87..f58f0d9 100644 --- a/data/lib/bugzillaDOMFunctions.js +++ b/data/lib/bugzillaDOMFunctions.js @@ -4,13 +4,13 @@ /** * Select option with given value on the with s for each category one if (catList) { - catList.forEach(function (cat) { + catList.forEach(function(cat) { optionElement = document.createElement("option"); optionElement.value = cat; - optionElement.setAttribute("id", "catId_" + - cat.replace(" ","").toLowerCase()); + optionElement.setAttribute("id", "catId_" + + cat.replace(" ", "").toLowerCase()); optionElement.appendChild(document.createTextNode(cat)); categoryList.appendChild(optionElement); }); } - categoryList.addEventListener("change", function (evt) { + categoryList.addEventListener("change", function(evt) { var selectedCategory = "[cat:" + this.value + "]"; - var whiteboardElement = document.getElementById("status_whiteboard"); + var whiteboardElement = document + .getElementById("status_whiteboard"); if (hasXorgBugsCategory()) { - whiteboardElement.value = whiteboardElement. - value.replace(catRE, ""); + whiteboardElement.value = whiteboardElement.value.replace( + catRE, ""); } addStuffToTextBox("status_whiteboard", selectedCategory); }, false); diff --git a/lib/cookiemanager.js b/lib/cookiemanager.js index 087d6ab..b777ab9 100644 --- a/lib/cookiemanager.js +++ b/lib/cookiemanager.js @@ -46,10 +46,10 @@ exports.getHostCookies = function getHostCookies(host) { if (cookie.rawHost == host) { result.push({ name: cookie.name, - value: cookie.value, + value: cookie.value }); } } return result; -} +}; diff --git a/lib/libbugzilla.js b/lib/libbugzilla.js index 7e2398b..c85d331 100644 --- a/lib/libbugzilla.js +++ b/lib/libbugzilla.js @@ -38,23 +38,26 @@ function log(msg) { } /** - * 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 + * 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 + // 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 + 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. - * + * 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. + * * This is a slow variant for bugs other than actual window */ function getRealBugNoSlow(bugNo, location, callback) { @@ -141,14 +144,11 @@ exports.changeJSONURL = function changeJSONURL() { }; /** - * - libbz.getInstalledPackages(msg.data, function (pkgsMsg) { - worker.postMessage(pkgsMsg); - - locationLoginObj: { - location: window.location.href, - login: getLogin() - } + * + * libbz.getInstalledPackages(msg.data, function (pkgsMsg) { + * worker.postMessage(pkgsMsg); + * + * locationLoginObj: { location: window.location.href, login: getLogin() } */ exports.getInstalledPackages = function getInstalledPackages(locationLoginObj, callback) { var installedPackages = {}; @@ -283,14 +283,16 @@ exports.createUpstreamBug = function createUpstreamBug(urlStr, subject, comment) }); }; -// Make a XML-RPC call ... most of the business logic should stay in the content script +// Make a XML-RPC call ... most of the business logic should stay in the content +// script exports.makeXMLRPCCall = function makeXMLRPCCall(url, login, method, params, callback) { var urlObj = urlMod.URL(url); getPassword(login, urlObj.schema + "://" + urlObj.host, function (passwObj) { if (!passwObj.password) { - // TODO this should happen, only when user presses Escape in password prompt + // TODO this should happen, only when user presses Escape in password + // prompt return null; } diff --git a/lib/logger.js b/lib/logger.js index ce96f69..ed9ac47 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -24,8 +24,10 @@ exports.initialize = function initialize(aMap) { }; exports.addLogRecord = function addLogRecord(rec) { - if (myStorage.storage.logs[rec.key] && myStorage.storage.logs[rec.key].comment) { - myStorage.storage.logs[rec.key].comment += "
    \n" + rec.comment; + if (myStorage.storage.logs[rec.key] + && myStorage.storage.logs[rec.key].comment) { + myStorage.storage.logs[rec.key].comment += "
    \n" + + rec.comment; } else { myStorage.storage.logs[rec.key] = rec; @@ -54,7 +56,7 @@ exports.importTimeSheet = function importTimeSheet() { if (fileMod.exists(filename)) { var otherTS = JSON.parse(fileMod.read(filename)); if (otherTS.logs) { - for (var rec in otherTS.logs) { + for ( var rec in otherTS.logs) { myStorage.storage.logs[rec] = otherTS.logs[rec]; } } @@ -74,27 +76,30 @@ function getBugzillaAbbr(url) { } exports.generateTimeSheet = function generateTimeSheet() { - var docHTML = timeSheetRecordsPrinter(myStorage.storage.logs, new Date()); - libbz.openURLInNewTab("data:text/html;charset=utf-8," + docHTML); -}; + var docHTML = timeSheetRecordsPrinter(myStorage.storage.logs, + new Date()); + libbz.openURLInNewTab("data:text/html;charset=utf-8," + + docHTML); +}; -var timeSheetRecordsPrinter = exports.timeSheetRecordsPrinter = - function timeSheetRecordsPrinter(records, date) { - var commentBugRE = new RegExp("[bB]ug\\s+([0-9]+)","g"); +var timeSheetRecordsPrinter = exports.timeSheetRecordsPrinter = function timeSheetRecordsPrinter( + records, date) { + var commentBugRE = new RegExp("[bB]ug\\s+([0-9]+)", "g"); // sort the records into temporary array var tmpArr = []; - var dateStr = date.getFullYear() + "-" + - xrpc.leadingZero(date.getMonth()+1) + "-" + - xrpc.leadingZero(date.getDate()); - var outStr = '' + - "\n"+ - "\n"+ - "TimeSheet-"+ dateStr + "\n\n\n" + - "

    TimeSheet

    \n"; + var dateStr = date.getFullYear() + "-" + + xrpc.leadingZero(date.getMonth() + 1) + "-" + + xrpc.leadingZero(date.getDate()); + var outStr = '' + "\n" + + "\n" + "TimeSheet-" + + dateStr + "\n\n\n" + + "

    TimeSheet

    \n"; - for (var i in records) { + for ( var i in records) { if (records.hasOwnProperty(i)) { - tmpArr.push( [ i, records[i] ]); + tmpArr.push([ + i, records[i] + ]); } } tmpArr.sort(function(a, b) { @@ -112,27 +117,24 @@ var timeSheetRecordsPrinter = exports.timeSheetRecordsPrinter = var currentDay = ""; // now print the array tmpArr.forEach(function(rec) { - var x = rec[1]; - var dayStr = utilMod.getISODate(x.date); - var host = urlMod.URL(x.url).host; - var BZName = getBugzillaAbbr(x.url); - var bugNo = utilMod.getBugNo(x.url); - if (dayStr != currentDay) { - currentDay = dayStr; - outStr += "

    " + currentDay - + "

    \n"; - } - // replace "bug ####" with a hyperlink to the current bugzilla - var comment = x.comment.replace(commentBugRE, - "$&"); - outStr += "

    Bug " - + BZName + "/" + bugNo + ": " - + x.title - + "" - + " \n
    " + comment + "

    \n"; + var x = rec[1]; + var dayStr = utilMod.getISODate(x.date); + var host = urlMod.URL(x.url).host; + var BZName = getBugzillaAbbr(x.url); + var bugNo = utilMod.getBugNo(x.url); + if (dayStr != currentDay) { + currentDay = dayStr; + outStr += "

    " + currentDay + + "

    \n"; + } + // replace "bug ####" with a hyperlink to the current bugzilla + var comment = x.comment.replace(commentBugRE, + "$&"); + outStr += "

    Bug " + BZName + + "/" + bugNo + ": " + x.title + "" + + " \n
    " + comment + "

    \n"; }); outStr += ""; return outStr; -} +}; diff --git a/lib/main.js b/lib/main.js index 849da68..f3e9458 100644 --- a/lib/main.js +++ b/lib/main.js @@ -23,13 +23,13 @@ function isOurPage(window, matchingURLs) { var url = window.location.href; // like ["regexp-url1", "regexp-url2"] - return matchingURLs.some(function (element,i,a) { + return matchingURLs.some(function(element, i, a) { return new RegExp(element).test(url); }); } /** - * + * */ function skipThisPage(doc) { var stemURL = "https://HOSTNAME/show_bug.cgi?id="; @@ -39,20 +39,21 @@ function skipThisPage(doc) { var hostname = doc.location.hostname; if (REArr) { var bugNo = REArr[1]; - doc.location = stemURL.replace("HOSTNAME",hostname) + bugNo; + doc.location = stemURL.replace("HOSTNAME", hostname) + bugNo; } } -var messageHandler = exports.messageHandler = function messageHandler(worker, msg) { +var messageHandler = exports.messageHandler = function messageHandler( + worker, msg) { switch (msg.cmd) { case "LogMessage": console.log(msg.data); break; case "ExecCmd": - libbz.executeCommand(msg.data); + libbz.executeCommand(msg.data); break; case "AddLogRecord": - logger.addLogRecord(msg.data); + logger.addLogRecord(msg.data); break; case "GenerateTS": logger.generateTimeSheet(); @@ -65,12 +66,12 @@ var messageHandler = exports.messageHandler = function messageHandler(worker, ms break; case "GetInstalledPackages": // send message with packages back - libbz.getInstalledPackages(msg.data, function (pkgsMsg) { + libbz.getInstalledPackages(msg.data, function(pkgsMsg) { worker.postMessage(pkgsMsg); }); break; case "GetClipboard": - libbz.getClipboard(function (clipboard) { + libbz.getClipboard(function(clipboard) { worker.postMessage(new Message(msg.data, clipboard)); }); break; @@ -91,18 +92,23 @@ var messageHandler = exports.messageHandler = function messageHandler(worker, ms break; case "MakeXMLRPCall": // url, login, method, params, callback - libbz.makeXMLRPCCall(msg.data.url, msg.data.login, msg.data.method, - msg.data.params, function(ret) { - worker.postMessage(new Message(msg.data.callRPC, ret)); - }); + libbz + .makeXMLRPCCall(msg.data.url, msg.data.login, + msg.data.method, msg.data.params, function(ret) { + worker.postMessage(new Message(msg.data.callRPC, + ret)); + }); break; case "GetURL": - libbz.getURL(msg.data.url, function(stuff) { - worker.postMessage(new Message(msg.data.backMessage, stuff)); - }); + libbz.getURL(msg.data.url, + function(stuff) { + worker.postMessage(new Message(msg.data.backMessage, + stuff)); + }); break; case "OpenBugUpstream": - libbz.createUpstreamBug(msg.data.url, msg.data.subject, msg.data.comment); + libbz.createUpstreamBug(msg.data.url, msg.data.subject, + msg.data.comment); break; case "testReady": // we ignore it here, interesting only in unit test @@ -113,36 +119,36 @@ var messageHandler = exports.messageHandler = function messageHandler(worker, ms }; var contentScriptLibraries = [ - self.data.url('lib/urltest.js'), - self.data.url("lib/util.js"), - self.data.url("lib/jumpNextBug.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/xorgBugCategories.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"), - self.data.url("lib/bzpage.js") + self.data.url('lib/urltest.js'), + self.data.url("lib/util.js"), + self.data.url("lib/jumpNextBug.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/xorgBugCategories.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"), + self.data.url("lib/bzpage.js") ]; -libbz.initialize(libbz.config, function () { +libbz.initialize(libbz.config, function() { pageMod.PageMod({ - include: [ - "https://bugzilla.redhat.com/show_bug.cgi?id=*", - "https://bugzilla.mozilla.org/show_bug.cgi?id=*", - "https://bugzilla.gnome.org/show_bug.cgi?id=*" + include : [ + "https://bugzilla.redhat.com/show_bug.cgi?id=*", + "https://bugzilla.mozilla.org/show_bug.cgi?id=*", + "https://bugzilla.gnome.org/show_bug.cgi?id=*" ], - contentScriptWhen: 'ready', - contentScriptFile: contentScriptLibraries, - onAttach: function onAttach(worker, msg) { - worker.on('message', function (msg) { + contentScriptWhen : 'ready', + contentScriptFile : contentScriptLibraries, + onAttach : function onAttach(worker, msg) { + worker.on('message', function(msg) { messageHandler(worker, msg); }); } @@ -150,34 +156,37 @@ libbz.initialize(libbz.config, function () { }); pageMod.PageMod({ - include: [ - "https://bugzilla.redhat.com/process_bug.cgi", - "https://bugzilla.redhat.com/post_bug.cgi", - "https://bugzilla.redhat.com/attachment.cgi", - "https://bugzilla.mozilla.org/process_bug.cgi", - "https://bugzilla.mozilla.org/post_bug.cgi", - "https://bugzilla.mozilla.org/attachment.cgi", - "https://bugzilla.gnome.org/process_bug.cgi", - "https://bugzilla.gnome.org/post_bug.cgi", - "https://bugzilla.gnome.org/attachment.cgi" + include : [ + "https://bugzilla.redhat.com/process_bug.cgi", + "https://bugzilla.redhat.com/post_bug.cgi", + "https://bugzilla.redhat.com/attachment.cgi", + "https://bugzilla.mozilla.org/process_bug.cgi", + "https://bugzilla.mozilla.org/post_bug.cgi", + "https://bugzilla.mozilla.org/attachment.cgi", + "https://bugzilla.gnome.org/process_bug.cgi", + "https://bugzilla.gnome.org/post_bug.cgi", + "https://bugzilla.gnome.org/attachment.cgi" ], - contentScriptWhen: 'ready', - contentScriptFile: self.data.url("lib/skip-bug.js") + contentScriptWhen : 'ready', + contentScriptFile : self.data.url("lib/skip-bug.js") }); - // Allow toggling of CC event displays using a context menu entry contextMenu.Item({ - label: "Toggle CC History", - contentScriptFile: [self.data.url('lib/urltest.js'), - self.data.url('lib/cc-context.js')] + label : "Toggle CC History", + contentScriptFile : [ + self.data.url('lib/urltest.js'), + self.data.url('lib/cc-context.js') + ] }); contextMenu.Item({ - label: "Copy Check-in Comment", - contentScriptFile: [self.data.url('lib/urltest.js'), - self.data.url('lib/checkin-context.js')], - onMessage: function (comment) { - require("clipboard").set(comment); + label : "Copy Check-in Comment", + contentScriptFile : [ + self.data.url('lib/urltest.js'), + self.data.url('lib/checkin-context.js') + ], + onMessage : function(comment) { + require("clipboard").set(comment); } }); diff --git a/lib/prompts.js b/lib/prompts.js index 7cfd3d1..3f34e0d 100644 --- a/lib/prompts.js +++ b/lib/prompts.js @@ -11,23 +11,23 @@ var promptTitle = "Bugzilla Triage Script"; /** * shows the text in a simple window - * + * * @return none */ exports.alert = function alert(msg) { var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"] - .getService(Ci.nsIPromptService); + .getService(Ci.nsIPromptService); prompts.alert(null, promptTitle, msg); }; /** * general prompts for a string method - * + * * @return String with the password */ exports.prompt = function prompt(prompt, defaultValue) { var stringValue = { - value: defaultValue ? defaultValue : "" + value : defaultValue ? defaultValue : "" }; var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"] @@ -44,7 +44,7 @@ exports.prompt = function prompt(prompt, defaultValue) { /** * returns password with a special password - * + * * @return String with the password */ exports.promptPassword = function promptPassword(prompt) { @@ -59,8 +59,8 @@ exports.promptPassword = function promptPassword(prompt) { var check = { value : true }; // default the checkbox to true - var result = prompts.promptPassword(null, "Bugzilla Triage Script", prompt, - password, null, check); + var result = prompts.promptPassword(null, + "Bugzilla Triage Script", prompt, password, null, check); // result is true if OK was pressed, false if cancel was pressed. // password.value is set if OK was pressed. // The checkbox is not displayed. @@ -83,8 +83,9 @@ exports.promptYesNoCancel = function promptOKNoCancel(prompt) { var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"] .getService(Ci.nsIPromptService); - var result = prompts.confirmEx(null, "Bugzilla Triage Script", prompt, - prompts.STD_YES_NO_BUTTONS, null, null, null, null, {}); + var result = prompts.confirmEx(null, "Bugzilla Triage Script", + prompt, prompts.STD_YES_NO_BUTTONS, null, null, null, + null, {}); if (result === 0) { return true; } @@ -97,22 +98,22 @@ exports.promptYesNoCancel = function promptOKNoCancel(prompt) { }; /** - * + * * documentation is https://developer.mozilla.org/en/NsIFilePicker */ -exports.promptFileOpenPicker = function promptFilePicker (win) { +exports.promptFileOpenPicker = function promptFilePicker(win) { var window = require("window-utils").activeWindow; var fp = Cc["@mozilla.org/filepicker;1"] - .createInstance(Ci.nsIFilePicker); + .createInstance(Ci.nsIFilePicker); fp.init(window, "JSON File Open", Ci.nsIFilePicker.modeOpen); fp.appendFilter("JSON files", "*.json"); fp.appendFilters(Ci.nsIFilePicker.filterAll); fp.filterIndex = 0; var res = fp.show(); - if (res === Ci.nsIFilePicker.returnOK || - res === Ci.nsIFilePicker.returnReplace ) { - return fp.file.path; + if (res === Ci.nsIFilePicker.returnOK + || res === Ci.nsIFilePicker.returnReplace) { + return fp.file.path; } return null; }; diff --git a/lib/util.js b/lib/util.js index d28f001..008d6fb 100644 --- a/lib/util.js +++ b/lib/util.js @@ -11,7 +11,7 @@ var urlMod = require("url"); /** * get parameters of URL as an object (name, value) */ -function getParamsFromURL (url, base) { +function getParamsFromURL(url, base) { if (!url || (url.toString().length === 0)) { throw new Error("Missing URL value!"); } @@ -23,7 +23,7 @@ function getParamsFromURL (url, base) { var paramsArr = url.path.split("?"); if (paramsArr.length === 1) { return {}; - } + } // get convert URL parameters to an Object var params = {}, s = []; @@ -35,11 +35,11 @@ function getParamsFromURL (url, base) { } /** - * Get a bug no from URL ... fails with aliases - * It should theoretically belong to bzpage.js, but we don't have - * unit tests there yet, so keeping here. - * - * @param url String with URL to be analyzed + * Get a bug no from URL ... fails with aliases It should theoretically belong + * to bzpage.js, but we don't have unit tests there yet, so keeping here. + * + * @param url + * String with URL to be analyzed * @return String with the bug ID (hopefully number, but not for aliases) */ exports.getBugNo = function getBugNo(url) { @@ -51,7 +51,7 @@ exports.getBugNo = function getBugNo(url) { /** * format date to be in ISO format (just day part) - * + * * @param date * @return string with the formatted date */ @@ -60,18 +60,15 @@ exports.getISODate = function getISODate(dateStr) { return n < 10 ? '0' + n : n; } var date = new Date(dateStr); - return date.getFullYear() + '-' + pad(date.getMonth() + 1) + '-' + - pad(date.getDate()); + return date.getFullYear() + '-' + pad(date.getMonth() + 1) + + '-' + pad(date.getDate()); }; /** - * object to pack messaging. Use as in - postMessage(new Message("GetPassword", { - login: login, - hostname: location.hostname - })); + * object to pack messaging. Use as in postMessage(new Message("GetPassword", { + * login: login, hostname: location.hostname })); */ exports.Message = function Message(cmd, data) { - this.cmd = cmd; - this.data = data; + this.cmd = cmd; + this.data = data; }; diff --git a/lib/xmlrpc.js b/lib/xmlrpc.js index e038c4e..3991b04 100644 --- a/lib/xmlrpc.js +++ b/lib/xmlrpc.js @@ -3,41 +3,44 @@ // Modification of Matěj Cepl released under the MIT/X11 license // http://www.opensource.org/licenses/mit-license.php /* - * + * * xmlrpc.js beta version 1 Tool for creating XML-RPC formatted requests in * JavaScript - * + * * Copyright 2001 Scott Andrew LePera scott@scottandrew.com - * - * + * + * * License: You are granted the right to use and/or redistribute this code only * if this license and the copyright notice are included and you accept that no * warranty of any kind is made or implied by the author. - * + * */ /** * checks whether parameter is an array - * - * @param obj Object + * + * @param obj + * Object * @return Boolean true if obj is array - * + * * The problem is that in different contexts, Array is not same, and so obj is * not an instance of SAME Array. */ /** * pads a single number with a leading zero. Heh. - * - * @param n String or Number + * + * @param n + * String or Number * @return String with leading zero added if necessary - * + * * If the real parameter is not numerical, it is just returned as it is. */ var leadingZero = exports.leadingZero = function leadingZero(n) { if (isNaN(Number(n))) { return n; - }; + } + ; var s = "0" + n; if (s.length > 2) { @@ -46,22 +49,24 @@ var leadingZero = exports.leadingZero = function leadingZero(n) { return s; }; -var dateToISO8601 = exports.dateToISO8601 = function dateToISO8601(date) { +var dateToISO8601 = exports.dateToISO8601 = function dateToISO8601( + date) { // wow I hate working with the Date object console.log("date = " + date); var year = date.getYear(); var month = leadingZero(date.getMonth()); var day = leadingZero(date.getDate()); - var time = leadingZero(date.getHours()) + - ":" + leadingZero(date.getMinutes()) + - ":" + leadingZero(date.getSeconds()); + var time = leadingZero(date.getHours()) + ":" + + leadingZero(date.getMinutes()) + ":" + + leadingZero(date.getSeconds()); var converted = year + month + day + "T" + time; console.log("date = " + converted); return converted; }; -var XMLRPCMessage = exports.XMLRPCMessage = function XMLRPCMessage(methodname) { +var XMLRPCMessage = exports.XMLRPCMessage = function XMLRPCMessage( + methodname) { this.method = methodname || "system.listMethods"; this.params = []; return this; @@ -71,20 +76,19 @@ XMLRPCMessage.prototype.myIsArray = function myIsArray(obj) { return (typeof obj.sort === 'function'); }; - -XMLRPCMessage.prototype.setMethod = function (methodName) { +XMLRPCMessage.prototype.setMethod = function(methodName) { if (methodName !== undefined) { this.method = methodName; } }; -XMLRPCMessage.prototype.addParameter = function (data) { +XMLRPCMessage.prototype.addParameter = function(data) { if (data !== undefined) { this.params.push(data); } }; -XMLRPCMessage.prototype.xml = function () { +XMLRPCMessage.prototype.xml = function() { var method = this.method; @@ -97,11 +101,11 @@ XMLRPCMessage.prototype.xml = function () { xml += "\n"; // do individual parameters - this.params.forEach(function (data) { + this.params.forEach(function(data) { xml += "\n"; - xml += "" + - this.getParamXML(this.dataTypeOf(data), - data) + "\n"; + xml += "" + + this.getParamXML(this.dataTypeOf(data), data) + + "\n"; xml += "\n"; }, this); xml += "\n"; @@ -110,7 +114,7 @@ XMLRPCMessage.prototype.xml = function () { return xml; // for now }; -XMLRPCMessage.prototype.dataTypeOf = function (o) { +XMLRPCMessage.prototype.dataTypeOf = function(o) { // identifies the data type var type = typeof (o); type = type.toLowerCase(); @@ -138,49 +142,50 @@ XMLRPCMessage.prototype.dataTypeOf = function (o) { return type; }; -XMLRPCMessage.prototype.doValueXML = function (type, data) { +XMLRPCMessage.prototype.doValueXML = function(type, data) { var xml = "<" + type + ">" + data + ""; return xml; }; -XMLRPCMessage.prototype.doBooleanXML = function (data) { +XMLRPCMessage.prototype.doBooleanXML = function(data) { var value = (data === true) ? 1 : 0; var xml = "" + value + ""; return xml; }; -XMLRPCMessage.prototype.doDateXML = function (data) { +XMLRPCMessage.prototype.doDateXML = function(data) { var xml = ""; xml += dateToISO8601(data); xml += ""; return xml; }; -XMLRPCMessage.prototype.doArrayXML = function (data) { +XMLRPCMessage.prototype.doArrayXML = function(data) { var xml = "\n"; - for (var i = 0; i < data.length; i++) { - xml += "" + - this.getParamXML(this.dataTypeOf(data[i]), - data[i]) + "\n"; + for ( var i = 0; i < data.length; i++) { + xml += "" + + this.getParamXML(this.dataTypeOf(data[i]), data[i]) + + "\n"; } xml += "\n"; return xml; }; -XMLRPCMessage.prototype.doStructXML = function (data) { +XMLRPCMessage.prototype.doStructXML = function(data) { var xml = "\n"; - for (var i in data) { + for ( var i in data) { xml += "\n"; xml += "" + i + "\n"; - xml += "" + this.getParamXML(this.dataTypeOf(data[i]), - data[i]) + "\n"; + xml += "" + + this.getParamXML(this.dataTypeOf(data[i]), data[i]) + + "\n"; xml += "\n"; } xml += "\n"; return xml; }; -XMLRPCMessage.prototype.getParamXML = function (type, data) { +XMLRPCMessage.prototype.getParamXML = function(type, data) { var xml; switch (type) { case "date": diff --git a/tests/pagemod-test-helpers.js b/tests/pagemod-test-helpers.js index 8621421..9980715 100644 --- a/tests/pagemod-test-helpers.js +++ b/tests/pagemod-test-helpers.js @@ -1,10 +1,10 @@ "use strict"; -const {Cc,Ci} = require("chrome"); - +const Cc = require("chrome").Cc; +const Ci = require("chrome").Ci; /** - * A helper function that creates a PageMod, then opens the specified URL - * and checks the effect of the page mod on 'onload' event via testCallback. + * A helper function that creates a PageMod, then opens the specified URL and + * checks the effect of the page mod on 'onload' event via testCallback. */ exports.testPageMod = function testPageMod(test, testURL, pageModOptions, testCallback, timeout) { @@ -20,7 +20,7 @@ exports.testPageMod = function testPageMod(test, testURL, pageModOptions, var browserWindow = wm.getMostRecentWindow("navigator:browser"); if (!browserWindow) { test.pass("page-mod tests: could not find the browser window, so " + - "will not run. Use -a firefox to run the pagemod tests.") + "will not run. Use -a firefox to run the pagemod tests."); return null; } @@ -44,7 +44,7 @@ exports.testPageMod = function testPageMod(test, testURL, pageModOptions, function onPageLoad() { b.removeEventListener("load", onPageLoad, true); testCallback(b.contentWindow.wrappedJSObject, function done() { - pageMods.forEach(function(mod) mod.destroy()); + pageMods.forEach(function(mod) {mod.destroy()}); // XXX leaks reported if we don't close the tab? tabBrowser.removeTab(newTab); test.done(); diff --git a/tests/test-color.js b/tests/test-color.js index eefb97d..95d3e16 100644 --- a/tests/test-color.js +++ b/tests/test-color.js @@ -1,31 +1,31 @@ /*global exports: false, require: false */ // TODO: add some failing tests as well "use strict"; -//var util = require("color"); +// var util = require("color"); // testing Color object -var ensureColorNew = function (test) { +var ensureColorNew = function(test) { var col = new util.Color(255, 255, 166); test.assertEqual(col.toString(), "#ffffa6", - "creation of new RGB Color object"); + "creation of new RGB Color object"); }; -var ensureColorUpdate = function (test) { +var ensureColorUpdate = function(test) { var col = new util.Color(255, 255, 166); col.update(255, 224, 176); test.assertEqual(col.toString(), "#ffe0b0", - "updating Color object"); + "updating Color object"); }; -var ensureColorHSL = function (test) { +var ensureColorHSL = function(test) { var col = new util.Color(255, 224, 176); test.assertEqual(col.hsl().toSource(), - "[0.10126582278481013, 1, 0.8450980392156863]", - "converting to HSL model"); + "[0.10126582278481013, 1, 0.8450980392156863]", + "converting to HSL model"); }; -var ensureColorLight = function (test) { +var ensureColorLight = function(test) { var col = new util.Color(255, 224, 176); test.assertEqual(col.lightColor().toString(), "#e8dcc9", - "getting a light color"); + "getting a light color"); }; diff --git a/tests/test-logger.js b/tests/test-logger.js index 2b087f8..d814838 100644 --- a/tests/test-logger.js +++ b/tests/test-logger.js @@ -6,34 +6,34 @@ var logMod = require("logger"); var selfMod = require("self"); var testGenerateTimeSheetDataLogs = { - "2010-07-27+bugzilla.redhat.com+533567": { - "date": "2010-07-27T21:28:47.103Z", - "url": "https://bugzilla.redhat.com/show_bug.cgi?id=533567", - "title": "KMS:RS480:X200M - GPU lockup (screen goes black)", - "comment": "removing filled in chip type for Guadec" + "2010-07-27+bugzilla.redhat.com+533567" : { + "date" : "2010-07-27T21:28:47.103Z", + "url" : "https://bugzilla.redhat.com/show_bug.cgi?id=533567", + "title" : "KMS:RS480:X200M - GPU lockup (screen goes black)", + "comment" : "removing filled in chip type for Guadec" }, - "2010-07-27+bugzilla.redhat.com+618769": { - "date": "2010-07-27T21:30:18.845Z", - "url": "https://bugzilla.redhat.com/show_bug.cgi?id=618769", - "title": "gdm and display unstable with ATI FirePro V3700 graphics card", - "comment": "asking for logs" + "2010-07-27+bugzilla.redhat.com+618769" : { + "date" : "2010-07-27T21:30:18.845Z", + "url" : "https://bugzilla.redhat.com/show_bug.cgi?id=618769", + "title" : "gdm and display unstable with ATI FirePro V3700 graphics card", + "comment" : "asking for logs" } }; -var testGenerateTimeSheetResultStr = "\n\n"+ - "TimeSheet-2011-04-17\n\n\n

    TimeSheet

    \n"+ - "

    2010-07-27

    \n

    "+ - "Bug RH/533567: "+ - "KMS:RS480:X200M - GPU lockup (screen goes black) \n
    removing filled "+ - "in chip type for Guadec

    \n

    Bug RH/618769: "+ - "gdm and display unstable with ATI FirePro V3700 graphics card \n"+ - "
    asking for logs

    \n"; +var testGenerateTimeSheetResultStr = "\n\n" + + "TimeSheet-2011-04-17\n\n\n

    TimeSheet

    \n" + + "

    2010-07-27

    \n

    " + + "Bug RH/533567: " + + "KMS:RS480:X200M - GPU lockup (screen goes black) \n
    removing filled " + + "in chip type for Guadec

    \n

    Bug RH/618769: " + + "gdm and display unstable with ATI FirePro V3700 graphics card \n" + + "
    asking for logs

    \n"; -exports.ensureTimeSheetRecordsPrinter = function (test) { - logMod.initialize(JSON.parse(selfMod.data.load( - "bugzillalabelAbbreviations.json"))) - test.assertEqual(logMod.timeSheetRecordsPrinter(testGenerateTimeSheetDataLogs, - new Date("2011-04-17")), testGenerateTimeSheetResultStr, - "Generates correct log report from given data."); +exports.ensureTimeSheetRecordsPrinter = function(test) { + logMod.initialize(JSON.parse(selfMod.data + .load("bugzillalabelAbbreviations.json"))); + test.assertEqual(logMod.timeSheetRecordsPrinter( + testGenerateTimeSheetDataLogs, new Date("2011-04-17")), + testGenerateTimeSheetResultStr, + "Generates correct log report from given data."); }; - diff --git a/tests/test-match-pattern.js b/tests/test-match-pattern.js index 9e3d2bd..106937a 100644 --- a/tests/test-match-pattern.js +++ b/tests/test-match-pattern.js @@ -1,11 +1,15 @@ -var { MatchPattern } = require("match-pattern"); +var MatchPattern = require("match-pattern").MatchPattern; -exports.ensureMatchPattern = function (test) { - var pattern = new MatchPattern("https://bugzilla.redhat.com/attachment.cgi"); +exports.ensureMatchPattern = function(test) { + var pattern = new MatchPattern( + "https://bugzilla.redhat.com/attachment.cgi"); console.log("pattern = " + pattern); - test.assert(pattern. - test("https://bugzilla.redhat.com/attachment.cgi"), "testing match pattern"); - test.assert(!pattern. - test("https://bugzilla.redhat.com/attachment.cgi?bugid=676538&action=enter"), - "testing failing match pattern"); + test.assert(pattern + .test("https://bugzilla.redhat.com/attachment.cgi"), + "testing match pattern"); + test + .assert( + !pattern + .test("https://bugzilla.redhat.com/attachment.cgi?bugid=676538&action=enter"), + "testing failing match pattern"); }; diff --git a/tests/test-pageMod.js b/tests/test-pageMod.js index 5434bbd..31cb3dd 100644 --- a/tests/test-pageMod.js +++ b/tests/test-pageMod.js @@ -13,126 +13,121 @@ var testURL = self.data.url('tests/change-more-bugs01.html'); var JSONifiedMessage = '{"cmd":"testMessage","data":{"a":"first","b":"second"}}'; exports.ensureMessagesWork = function(test) { - var msg = new utilMod.Message("testMessage", { a: "first", b: "second" } ); + var msg = new utilMod.Message("testMessage", { + a : "first", + b : "second" + }); test.assertEqual(msg.cmd, "testMessage", - "msg.cmd comes over well"); + "msg.cmd comes over well"); test.assertEqual(msg.data.a, "first", - "msg.data.a comes over well"); + "msg.data.a comes over well"); test.assertEqual(msg.data.b, "second", - "msg.data.b comes over well"); + "msg.data.b comes over well"); test.assertEqual(JSON.stringify(msg), JSONifiedMessage, - "JSONification of Message works as well"); + "JSONification of Message works as well"); }; /* + * + * var theURL = main.theURL; var testURL = + * self.data.url('tests/change-more-bugs01.html'); + * + * var contentScriptLibraries = { "bugzilla.redhat.com": [ + * self.data.url("util.js"), self.data.url("color.js"), + * self.data.url("rhbzpage.js"), self.data.url("bzpage.js") ] }; + * + * libbz.initialize(libbz.config, function () { pageMod.PageMod({ include: [ + * "https://bugzilla.redhat.com/show_bug.cgi?id=*" ], contentScriptWhen: + * 'ready', contentScriptFile: contentScriptLibraries["bugzilla.redhat.com"], + * onAttach: function onAttach(worker, msg) { console.log("worker: " + worker); + * worker.on('message', function (msg) { messageHandler(worker, msg); }); } }); + * }); + * + * pageMod.PageMod({ include: [ "https://bugzilla.redhat.com/process_bug.cgi" ], + * contentScriptWhen: 'ready', contentScriptFile: self.data.url("skip-bug.js") + * }); + */ -var theURL = main.theURL; -var testURL = self.data.url('tests/change-more-bugs01.html'); - -var contentScriptLibraries = { - "bugzilla.redhat.com": [ - self.data.url("util.js"), - self.data.url("color.js"), - self.data.url("rhbzpage.js"), - self.data.url("bzpage.js") - ] -}; - -libbz.initialize(libbz.config, function () { - pageMod.PageMod({ - include: [ - "https://bugzilla.redhat.com/show_bug.cgi?id=*" - ], - contentScriptWhen: 'ready', - contentScriptFile: contentScriptLibraries["bugzilla.redhat.com"], - onAttach: function onAttach(worker, msg) { - console.log("worker: " + worker); - worker.on('message', function (msg) { - messageHandler(worker, msg); - }); +var ensureSimplePageLoad = function(test) { + console.log("testURL = " + testURL); + testPageMod(test, testURL, [ + { + include : [ + "*" + ], + contentScriptWhen : 'ready', + contentScriptFile : [ + self.data.url("libPW.js"), + self.data.url("simplePageWorker.js") + ], + onAttach : function onAttach(worker) { + worker.on('message', function(msg) { + switch (msg.cmd) { + case "LogMessage": + log(msg.data); + break; + case "CallBack": + worker + .postMessage(new utilMod.Message("Main", null)); + break; + default: + console.error(msg); + } + }); + } } + ], function(win, done) { + test.assertNotEqual(win.document + .getElementsByTagName("form")[0], null, + "test of loading the page"); + done(); }); -}); - -pageMod.PageMod({ - include: [ - "https://bugzilla.redhat.com/process_bug.cgi" - ], - contentScriptWhen: 'ready', - contentScriptFile: self.data.url("skip-bug.js") -}); - */ - -var ensureSimplePageLoad = function (test) { - console.log("testURL = " + testURL); - testPageMod(test, testURL, [{ - include: ["*"], - contentScriptWhen: 'ready', - contentScriptFile: [ - self.data.url("libPW.js"), - self.data.url("simplePageWorker.js") - ], - onAttach: function onAttach(worker) { - worker.on('message', function (msg) { - switch (msg.cmd) { - case "LogMessage": - log(msg.data); - break; - case "CallBack": - worker.postMessage(new utilMod.Message("Main", null)); - break; - default: - console.error(msg); - } - }); - } - }], - function (win, done) { - test.assertNotEqual(win.document.getElementsByTagName("form")[0], - null, "test of loading the page"); - done(); - }); }; -var ensurePageLoadsWell = function (test) { +var ensurePageLoadsWell = function(test) { var wm = Cc['@mozilla.org/appshell/window-mediator;1'] - .getService(Ci.nsIWindowMediator); - var browserWindow = wm.getMostRecentWindow("navigator:browser"); + .getService(Ci.nsIWindowMediator); + var browserWindow = wm + .getMostRecentWindow("navigator:browser"); if (!browserWindow) { - test.fail("page-mod tests: could not find the browser window, so " + - "will not run. Use -a firefox to run the pagemod tests."); - return null; + test + .fail("page-mod tests: could not find the browser window, so " + + "will not run. Use -a firefox to run the pagemod tests."); + return null; } var loader = test.makeSandboxedLoader(); var pageMod = loader.require("page-mod"); - var testDoc = {}, b = {}, tabBrowser = {}, newTab = {}; + var testDoc = {}, b = {}, tabBrowser = {}, newTab = {}; pageMod.PageMod({ - include: ["*"], - contentScriptWhen: 'ready', - contentScriptFile: [ - self.data.url("libPW.js"), - self.data.url("pageWorker.js") - ], - onAttach: function onAttach(worker) { - worker.on('message', function (msg) { - switch (msg.cmd) { - case "testReady": - testDoc = b.contentWindow.wrappedJSObject.document; - test.assertNotEqual(testDoc.getElementById("dupeid_action"), - null, "test of DOM modifications of the page"); - pageMod.destroy(); - tabBrowser.removeTab(newTab); - test.done(); - // the test itself - break; - default: - main.messageHandler(worker, msg); - } - }); - } - }); + include : [ + "*" + ], + contentScriptWhen : 'ready', + contentScriptFile : [ + self.data.url("libPW.js"), + self.data.url("pageWorker.js") + ], + onAttach : function onAttach(worker) { + worker.on('message', function(msg) { + switch (msg.cmd) { + case "testReady": + testDoc = b.contentWindow.wrappedJSObject.document; + test.assertNotEqual(testDoc + .getElementById("dupeid_action"), null, + "test of DOM modifications of the page"); + pageMod.destroy(); + tabBrowser.removeTab(newTab); + test.done(); + // the test itself + break; + default: + main.messageHandler(worker, msg); + } + }); + } + }); tabBrowser = browserWindow.gBrowser; newTab = tabBrowser.addTab(testURL); diff --git a/tests/test-util.js b/tests/test-util.js index 26c5f6d..7ab6280 100644 --- a/tests/test-util.js +++ b/tests/test-util.js @@ -6,13 +6,13 @@ var util = require("util"); var urlMod = require("url"); // testing util.heir -var ensureHeir = function (test) { +var ensureHeir = function(test) { var fedlimid = {}, naoise = {}; function Father(x) { this.family = x; } - + Father.prototype.getFamily = function getFamily() { return this.family; }; @@ -21,194 +21,216 @@ var ensureHeir = function (test) { Father.call(this, x); this.wife = w; } - + Son.prototype = util.heir(Father); Son.prototype.constructor = Son; - + Son.prototype.getWife = function getWife() { return this.wife; }; - + Son.prototype.getFamily = function getFamily() { - var upFamily = - Father.prototype.getFamily.call(this); + var upFamily = Father.prototype.getFamily.call(this); return upFamily + ", " + this.wife; }; - + // for curious and non-Celtic // http://en.wikipedia.org/wiki/Deirdre :) fedlimid = new Father("mac Daill"); naoise = new Son("Usnech", "Deirdre"); - + test.assertEqual(fedlimid.getFamily(), "mac Daill", - "checking creation of new simple object"); - + "checking creation of new simple object"); + test.assertEqual(naoise.getWife(), "Deirdre", - "checking creation of new daughter object"); + "checking creation of new daughter object"); test.assertEqual(naoise.getFamily(), "Usnech, Deirdre", - "checking creation of new overloaded method"); + "checking creation of new overloaded method"); }; // testing util.isInList -var ensureIsInListTrue = function (test) { - test.assert(util.isInList("a", ["a"]), - "conversion of a string to an array"); +var ensureIsInListTrue = function(test) { + test.assert(util.isInList("a", [ + "a" + ]), "conversion of a string to an array"); }; -var ensureIsInListFalse = function (test) { - test.assert(!util.isInList("b", ["a"]), - "conversion of a string to an array"); +var ensureIsInListFalse = function(test) { + test.assert(!util.isInList("b", [ + "a" + ]), "conversion of a string to an array"); }; -var ensureIsInListEmpty = function (test) { +var ensureIsInListEmpty = function(test) { test.assert(!util.isInList("b", []), - "conversion of a string to an array"); + "conversion of a string to an array"); }; -var ensureIsInListNoMember = function (test) { - test.assert(!util.isInList("", ["x"]), - "conversion of a string to an array"); +var ensureIsInListNoMember = function(test) { + test.assert(!util.isInList("", [ + "x" + ]), "conversion of a string to an array"); }; // testing util.filterByRegexp -var ensureFilterByRegexp = function (test) { +var ensureFilterByRegexp = function(test) { var list = [ - { - "regexp": "test(ing|ed)", - "addr": "correct" - }, - { - "regexp": "ba.*d", - "addr": true - } + { + "regexp" : "test(ing|ed)", + "addr" : "correct" + }, { + "regexp" : "ba.*d", + "addr" : true + } ]; - - test.assertEqual(util.filterByRegexp(list, "testing"), "correct", - "simple testing of filterByRegexp"); - test.assertEqual(util.filterByRegexp(list, "unknown value"), "", - "simple testing of filterByRegexp with non-found address"); - test.assert(util.filterByRegexp(list, "baaad"), - "simple testing of filterByRegexp with non-string return value"); + + test.assertEqual(util.filterByRegexp(list, "testing"), + "correct", "simple testing of filterByRegexp"); + test.assertEqual(util.filterByRegexp(list, "unknown value"), + "", + "simple testing of filterByRegexp with non-found address"); + test + .assert(util.filterByRegexp(list, "baaad"), + "simple testing of filterByRegexp with non-string return value"); }; -var ensureFilterByRegexpEmpty = function (test) { - test.assertRaises(function () { - util.filterByRegexp(undefined, "tralala"); - }, - "list is undefined", - "filterByRegexp throws an exception with empty list"); +var ensureFilterByRegexpEmpty = function(test) { + test.assertRaises(function() { + util.filterByRegexp(undefined, "tralala"); + }, "list is undefined", + "filterByRegexp throws an exception with empty list"); }; // testing util.getISODate -var ensureGetISODate = function (test) { - test.assertEqual(util.getISODate("Mon May 31 2010 23:29:09 GMT+0200 (CET)"), - "2010-05-31", "conversion of a Date to ISO-formatted String"); +var ensureGetISODate = function(test) { + test.assertEqual(util + .getISODate("Mon May 31 2010 23:29:09 GMT+0200 (CET)"), + "2010-05-31", + "conversion of a Date to ISO-formatted String"); }; // testing util.valToArray -var ensureValToArrayString = function (test) { - test.assertEqual(JSON.stringify(util.valToArray("a")), - JSON.stringify(["a"]), - "conversion of a string to an array"); +var ensureValToArrayString = function(test) { + test.assertEqual(JSON.stringify(util.valToArray("a")), JSON + .stringify([ + "a" + ]), "conversion of a string to an array"); }; -var ensureValToArrayEmpty = function (test) { - test.assertEqual(JSON.stringify(util.valToArray("")), - JSON.stringify([""]), - "conversion of an empty string to an array"); +var ensureValToArrayEmpty = function(test) { + test.assertEqual(JSON.stringify(util.valToArray("")), JSON + .stringify([ + "" + ]), "conversion of an empty string to an array"); }; -var ensureValToArrayArray = function (test) { - test.assertEqual(JSON.stringify(util.valToArray(["a"])), - JSON.stringify(["a"]), - "non-conversion of an array"); +var ensureValToArrayArray = function(test) { + test.assertEqual(JSON.stringify(util.valToArray([ + "a" + ])), JSON.stringify([ + "a" + ]), "non-conversion of an array"); }; // testing util.addCSVValue -var ensureCSVAddedToNull = function (test) { +var ensureCSVAddedToNull = function(test) { test.assertEqual(util.addCSVValue("", "b"), "b", - "adding a string to empty string"); + "adding a string to empty string"); }; -var ensureCSVAddedNull = function (test) { +var ensureCSVAddedNull = function(test) { test.assertEqual(util.addCSVValue("a", ""), "a", - "adding nothing to a string"); + "adding nothing to a string"); }; -var ensureCSVAddedString = function (test) { +var ensureCSVAddedString = function(test) { test.assertEqual(util.addCSVValue("a", "b"), "a, b", - "adding one string to another one"); + "adding one string to another one"); }; -var ensureCSVAddedArray = function (test) { - test.assertEqual(util.addCSVValue("a", ["b", "c"]), "a, b, c", - "adding array to a string"); +var ensureCSVAddedArray = function(test) { + test.assertEqual(util.addCSVValue("a", [ + "b", "c" + ]), "a, b, c", "adding array to a string"); }; -var ensureCSVAddedArray2Array = function (test) { - test.assertEqual(util.addCSVValue("a, b", ["c", "d"]), "a, b, c, d", - "adding one array to another"); +var ensureCSVAddedArray2Array = function(test) { + test.assertEqual(util.addCSVValue("a, b", [ + "c", "d" + ]), "a, b, c, d", "adding one array to another"); }; // testing util.removeCSVValue -var ensureCSVRemoveSimple = function (test) { +var ensureCSVRemoveSimple = function(test) { test.assertEqual(util.removeCSVValue("a, b", "b"), "a", - "removing one string from an array"); + "removing one string from an array"); }; // also checking a tolerancy against different ways of writing arrays -var ensureCSVRemoveNonMember = function (test) { - test.assertEqual(util.removeCSVValue("a,b", "c"), "a, b", - "removing a string from an array of which it isn't a member"); +var ensureCSVRemoveNonMember = function(test) { + test + .assertEqual(util.removeCSVValue("a,b", "c"), "a, b", + "removing a string from an array of which it isn't a member"); }; -var ensureCSVRemoveEmpty = function (test) { +var ensureCSVRemoveEmpty = function(test) { test.assertEqual(util.removeCSVValue("", "c"), "", - "removing a string from an empty array"); + "removing a string from an empty array"); }; // testing util.getObjectKeys -var ensureGetObjectKeys = function (test) { +var ensureGetObjectKeys = function(test) { var testObj = { - a: 1, - b: 2 + a : 1, + b : 2 }; test.assertEqual(JSON.stringify(util.getObjectKeys(testObj)), - JSON.stringify(["a", "b"]), - "getting keys from a object"); + JSON.stringify([ + "a", "b" + ]), "getting keys from a object"); }; // testing util.getParamsFromURL -var ensureGetParamsFromURL = function (test) { - test.assertEqual(JSON.stringify(util.getParamsFromURL("https://bugzilla.redhat.com/show_bug.cgi?id=549066")), - JSON.stringify({id:"549066"}), - "simply compare result of bugzilla show_page URL"); - var complexURL = new urlMod.URL("http://www.google.com/search?ie=UTF-8&oe=UTF-8&sourceid=navclient"+ - "&gfns=1&q=gg+javascript+url+parse"); - test.assertEqual(JSON.stringify(util.getParamsFromURL(complexURL)), - JSON.stringify({ - "ie":"UTF-8", - "oe":"UTF-8", - "sourceid":"navclient", - "gfns":"1", - "q":"gg+javascript+url+parse" - }), - "simply compare result of bugzilla show_page URL"); - test.assertEqual(JSON.stringify(util.getParamsFromURL("https://bugzilla.redhat.com/")), - JSON.stringify({}), - "URL without any parameters"); - test.assertRaises(function () {util.getParamsFromURL("");}, - "Missing URL value!", "No URL"); +var ensureGetParamsFromURL = function(test) { + test + .assertEqual( + JSON + .stringify(util + .getParamsFromURL("https://bugzilla.redhat.com/show_bug.cgi?id=549066")), + JSON.stringify({ + id : "549066" + }), "simply compare result of bugzilla show_page URL"); + var complexURL = new urlMod.URL( + "http://www.google.com/search?ie=UTF-8&oe=UTF-8&sourceid=navclient" + + "&gfns=1&q=gg+javascript+url+parse"); + test.assertEqual(JSON.stringify(util + .getParamsFromURL(complexURL)), JSON.stringify({ + "ie" : "UTF-8", + "oe" : "UTF-8", + "sourceid" : "navclient", + "gfns" : "1", + "q" : "gg+javascript+url+parse" + }), "simply compare result of bugzilla show_page URL"); + test.assertEqual(JSON.stringify(util + .getParamsFromURL("https://bugzilla.redhat.com/")), JSON + .stringify({}), "URL without any parameters"); + test.assertRaises(function() { + util.getParamsFromURL(""); + }, "Missing URL value!", "No URL"); }; // testing util.getBugNo -var ensureGetBugNo = function (test) { - var bugNo = util.getBugNo("https://bugzilla.redhat.com/show_bug.cgi?id=597141"); +var ensureGetBugNo = function(test) { + var bugNo = util + .getBugNo("https://bugzilla.redhat.com/show_bug.cgi?id=597141"); test.assertEqual(bugNo, 597141, "getting bug number"); - bugNo = util.getBugNo("https://bugzilla.redhat.com/show_bug.cgi?id=serialWacom"); - test.assertEqual(bugNo, "serialWacom", "getting a bug alias; there is no guarantee of getting number!"); + bugNo = util + .getBugNo("https://bugzilla.redhat.com/show_bug.cgi?id=serialWacom"); + test + .assertEqual(bugNo, "serialWacom", + "getting a bug alias; there is no guarantee of getting number!"); }; diff --git a/tests/test-xmlrpc.js b/tests/test-xmlrpc.js index f3f2e56..78bf9d5 100644 --- a/tests/test-xmlrpc.js +++ b/tests/test-xmlrpc.js @@ -2,21 +2,21 @@ /*jslint plusplus: false */ "use strict"; var xrpc = require("xmlrpc"); -var xmlOut = "\n" + - "\nbugzilla.updateAttachMimeType\n" + - "\n\n\n\nattach_id\n" + - "myId\n\n\n" + - "mime_type\ntext/plain\n\n" + - "\nnomail\nbillg@microsoft.com" + - "\n\n\n\n\n\n" + - "me@example.com\n\n" + - "\nsecret\n\n" + - "\n3.14\n\n" + - "\n1\n\n" + - "\n"; +var xmlOut = "\n" + + "\nbugzilla.updateAttachMimeType\n" + + "\n\n\n\nattach_id\n" + + "myId\n\n\n" + + "mime_type\ntext/plain\n\n" + + "\nnomail\nbillg@microsoft.com" + + "\n\n\n\n\n\n" + + "me@example.com\n\n" + + "\nsecret\n\n" + + "\n3.14\n\n" + + "\n1\n\n" + + "\n"; -exports.ensureLeadingZero = function (test) { - test.assert(typeof(xrpc.leadingZero) == "function"); +exports.ensureLeadingZero = function(test) { + test.assert(typeof (xrpc.leadingZero) == "function"); test.assertEqual(xrpc.leadingZero("1"), "01"); test.assertEqual(xrpc.leadingZero(1), "01"); test.assertEqual(xrpc.leadingZero("11"), "11"); @@ -25,12 +25,13 @@ exports.ensureLeadingZero = function (test) { test.assertEqual(xrpc.leadingZero(111), "111"); test.assertEqual(xrpc.leadingZero("-1"), "-1"); test.assertEqual(xrpc.leadingZero(-1), "-1"); - test.assertEqual(xrpc.leadingZero("zzz"),"zzz"); + test.assertEqual(xrpc.leadingZero("zzz"), "zzz"); }; // testing xrpc.XMLRPCMessage -exports.ensureGenerateXMLRPC = function (test) { - var msg = new xrpc.XMLRPCMessage("bugzilla.updateAttachMimeType"); +exports.ensureGenerateXMLRPC = function(test) { + var msg = new xrpc.XMLRPCMessage( + "bugzilla.updateAttachMimeType"); msg.addParameter({ 'attach_id' : "myId", 'mime_type' : "text/plain", @@ -40,6 +41,6 @@ exports.ensureGenerateXMLRPC = function (test) { msg.addParameter("secret"); msg.addParameter(3.14); msg.addParameter(true); - test.assertEqual(msg.xml(), xmlOut, - "generate XML-RPC message"); + test + .assertEqual(msg.xml(), xmlOut, "generate XML-RPC message"); }; -- cgit From 7b6eefcd506ec03e1db422ca6e1f4f1bb8420d1c Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 28 Apr 2011 14:28:10 +0200 Subject: Reorganization. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fixingAttMIME, rhbzpage, xorgBugCategories moved to data/rhlib directory, * docs directory removed ... keep documentation in JSDocs; rewrite in MD is a waste of time. * move Ehsan’s scripts to separate data/tweaks directory. --- data/lib/addNewLinks.js | 77 --- data/lib/bug-page-mod.js | 1013 ----------------------------------- data/lib/cc-context.js | 8 - data/lib/checkin-context.js | 13 - data/lib/fixingAttMIME.js | 90 ---- data/lib/preprocessDuplicates.js | 132 ----- data/lib/rhbzpage.js | 512 ------------------ data/lib/urltest.js | 5 - data/lib/viewSource.js | 104 ---- data/lib/xorgBugCategories.js | 74 --- data/rhlib/fixingAttMIME.js | 90 ++++ data/rhlib/rhbzpage.js | 512 ++++++++++++++++++ data/rhlib/xorgBugCategories.js | 74 +++ data/tweaks/addNewLinks.js | 77 +++ data/tweaks/bug-page-mod.js | 1013 +++++++++++++++++++++++++++++++++++ data/tweaks/cc-context.js | 8 + data/tweaks/checkin-context.js | 13 + data/tweaks/preprocessDuplicates.js | 132 +++++ data/tweaks/urltest.js | 5 + data/tweaks/viewSource.js | 104 ++++ docs/bzpage.md | 0 docs/rhbzpage.md | 0 docs/xhr.md | 82 --- lib/main.js | 24 +- 24 files changed, 2040 insertions(+), 2122 deletions(-) delete mode 100644 data/lib/addNewLinks.js delete mode 100644 data/lib/bug-page-mod.js delete mode 100644 data/lib/cc-context.js delete mode 100644 data/lib/checkin-context.js delete mode 100644 data/lib/fixingAttMIME.js delete mode 100644 data/lib/preprocessDuplicates.js delete mode 100644 data/lib/rhbzpage.js delete mode 100644 data/lib/urltest.js delete mode 100644 data/lib/viewSource.js delete mode 100644 data/lib/xorgBugCategories.js create mode 100644 data/rhlib/fixingAttMIME.js create mode 100644 data/rhlib/rhbzpage.js create mode 100644 data/rhlib/xorgBugCategories.js create mode 100644 data/tweaks/addNewLinks.js create mode 100644 data/tweaks/bug-page-mod.js create mode 100644 data/tweaks/cc-context.js create mode 100644 data/tweaks/checkin-context.js create mode 100644 data/tweaks/preprocessDuplicates.js create mode 100644 data/tweaks/urltest.js create mode 100644 data/tweaks/viewSource.js delete mode 100644 docs/bzpage.md delete mode 100644 docs/rhbzpage.md delete mode 100644 docs/xhr.md diff --git a/data/lib/addNewLinks.js b/data/lib/addNewLinks.js deleted file mode 100644 index b8e7bd2..0000000 --- a/data/lib/addNewLinks.js +++ /dev/null @@ -1,77 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Bugzilla Tweaks. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Johnathan Nightingale - * Ehsan Akhgari - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -function addNewLinks(d) { - var product = d - .querySelector("#field_container_product option[selected]"); - var component = d.querySelector("#component option[selected]"); - - if (product) { - var label = d.getElementById('field_container_product'); - var url = 'enter_bug.cgi?product=' - + encodeURIComponent(product.value); - if (label) { - createDeadLink("file_new_bug_product", "new", label, url, - [], "parens"); - } - } - - if (product && component) { - var select = d.querySelector("select#component"); - var label = select.parentNode; - var url = 'enter_bug.cgi?product=' - + encodeURIComponent(product.value) + '&component=' - + encodeURIComponent(component.value); - if (label) { - var componentElement = document - .getElementById("bz_component_input"); - if (componentElement) { // We are in the Red Hat bugzilla - // do we have components list visible? - if (document.getElementById('bz_component_input').classList - .contains("bz_default_hidden")) { - label = document - .getElementById("bz_component_edit_container"); - } - } - else { - label = document.getElementById('component').parentNode; - } - createDeadLink("file_new_bug_component", "new", label, - url, [], "parens"); - } - } -} diff --git a/data/lib/bug-page-mod.js b/data/lib/bug-page-mod.js deleted file mode 100644 index a7fb7e7..0000000 --- a/data/lib/bug-page-mod.js +++ /dev/null @@ -1,1013 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Bugzilla Tweaks. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Johnathan Nightingale - * Ehsan Akhgari - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -function tweakBugzilla(d) { - // run on both bugzilla.m.o and bugzilla-stage-tip.m.o - // if (!onBugzillaPage(d.URL)) - // return; - - // Put the quicksearch text in the quicksearch boxes - quicksearchHandler(d); - - if (!d.getElementById("comments")) // don't process the mid-air collision - // pages - return; - - // Make the comment box bigger ... TODO not necessary on RH BZ, but doesn't hurt - var commentBox = d.getElementById("comment"); - if (commentBox) - commentBox.rows=20; - - addNewLinks(d); - - attachmentDiffLinkify(d); - - viewAttachmentSource(d); - - // Mark up history along right hand edge - // TODO ... not sure what does this mean ... this - // element is I suppose everywhere. - var historyLink = d.querySelector("link[title='Bug Activity']"); - if (!historyLink) - return; - - // Add our own style for bugzilla-tweaks - var style = d.createElement("style"); - style.setAttribute("type", "text/css"); - style.appendChild(d.createTextNode( - ".bztw_history { border: none; font-weight: normal; width: 58em; margin-left: 5em; }" + - ".bztw_inlinehistory { font-weight: normal; width: 56em; }" + - ".bztw_history .old, .bztw_inlinehistory .old { text-decoration: line-through; }" + - ".bztw_history .sep:before { content: \" \"; }" + - ".bztw_unconfirmed { font-style: italic; }" + - "tr.bz_tr_obsolete.bztw_plusflag { display: table-row !important; }" + - '.bztw_historyitem + .bztw_historyitem:before { content: "; "; }' - )); - d.getElementsByTagName("head")[0].appendChild(style); - style = d.createElement("style"); - style.setAttribute("type", "text/css"); - style.id = "bztw_cc"; - style.appendChild(d.createTextNode( - ".bztw_cc { display: none; }" + - '.bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: ""; }' + - '.bztw_historyitem:not([class~="bztw_cc"]) ~ .bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: "; "; }' - )); - d.getElementsByTagName("head")[0].appendChild(style); - - var userNameCache = {}; - function getUserName(email) { - if (email in userNameCache) { - return userNameCache[email]; - } - var emailLink = d.querySelectorAll("a.email"); - for (var i = 0; i < emailLink.length; ++i) { - if (emailLink[i].href == "mailto:" + email) { - return userNameCache[email] = htmlEncode(trimContent(emailLink[i])); - } - } - return email; - } - - // collect the flag names - var flagNames = [], flags = {}, flagOccurrences = {}; - var flagRows = d.querySelectorAll("#flags tr"); - for (var i = 0; i < flagRows.length; ++i) { - var item = flagRows[i].querySelectorAll("td"); - if (!item[1]) - continue; - var name = trimContent(item[1]).replace('\u2011', '-', 'g'); - flagNames.push(name); - flags[name] = item[1]; - } - flagRows = d.querySelectorAll(".field_label[id^=field_label_cf_]"); - for (var i = 0; i < flagRows.length; ++i) { - var name = trimContent(flagRows[i]).replace(/\:$/, '') - .replace('\u2011', '-', 'g'); - flagNames.push(name); - flags[name] = flagRows[i]; - } - var flagCounter = 1; - - // ================================================= - function findFlag(item) { - function lookup(names) { - names = names.split(", "); - var results = []; - for (var j = 0; j < names.length; ++j) { - var name = names[j].replace('\u2011', '-', 'g'); - for (var i = 0; i < flagNames.length; ++i) { - var quotedFlagName = flagNames[i].replace('.', '\\.', 'g') - .replace('\u2011', '-', 'g'); - if ((new RegExp('^' + quotedFlagName)).test(name)) { - results.push(flagNames[i]); - break; - } - } - } - return results; - } - var base = item[4] ? 2 : 0; - // handle normal flags - if (trimContent(item[base]) == 'Flags') { - var result = lookup(trimContent(item[base + 1])). - concat(lookup(trimContent(item[base + 2]))); - return result; - } - // handle special pseudo-flags - return lookup(trimContent(item[base])); - } - - var DataStore = new DataStoreCtor(d); - - var AttachmentFlagHandler = new AttachmentFlagHandlerCtor(); - AttachmentFlagHandler.determineInterestingFlags(d); - - var CheckinComment = new CheckinCommentCtor(); - CheckinComment.initialize(d, AttachmentFlagHandler._interestingFlags); - - var iframe = d.createElement('iframe'); - iframe.src = historyLink.href; - iframe.style.display = "none"; - iframe.addEventListener("load", function() { - preprocessDuplicateMarkers(d, iframe.contentDocument); - - var historyItems = iframe.contentDocument.querySelectorAll('#bugzilla-body tr'); - var commentTimes = d.querySelectorAll('.bz_comment_time'); - - // Sometimes the history will stack several changes together, - // and we'll want to append the data from the Nth item to the - // div created in N-1 - var i=0, j=0, flagsFound; - for (; i < historyItems.length; i++) { - var item = historyItems[i].querySelectorAll("td"); - if (!item[1]) - continue; - - var reachedEnd = false; - for (; j < commentTimes.length; j++) { - if (trimContent(item[1]) > trimContent(commentTimes[j])) { - if (j < commentTimes.length - 1) { - continue; - } else { - reachedEnd = true; - } - } - - var commentHead = commentTimes[j].parentNode; - - var mainUser = commentHead.querySelector(".bz_comment_user a.email") - .href - .substr(7); - var user = trimContent(item[0]); - var mainTime = trimContent(commentTimes[j]); - var time = trimContent(item[1]); - var inline = (mainUser == user && time == mainTime); - - var currentDiv = d.createElement("div"); - var userPrefix = ''; - if (inline) { - // assume that the change was made by the same user - commentHead.appendChild(currentDiv); - currentDiv.setAttribute("class", "bztw_inlinehistory"); - } else { - // the change was made by another user - if (!reachedEnd) { - var parentDiv = commentHead.parentNode; - if (parentDiv.previousElementSibling && - parentDiv.previousElementSibling.className.indexOf("bztw_history") >= 0) { - currentDiv = parentDiv.previousElementSibling; - } else { - parentDiv.parentNode.insertBefore(currentDiv, parentDiv); - } - } else { - var parentDiv = commentHead.parentNode; - if (parentDiv.nextElementSibling && - parentDiv.nextElementSibling.className.indexOf("bztw_history") >= 0) { - currentDiv = parentDiv.nextElementSibling; - } else { - parentDiv.parentNode.appendChild(currentDiv); - } - } - currentDiv.setAttribute("class", "bz_comment bztw_history"); - userPrefix += "" + - getUserName(trimContent(item[0])) + ": "; - } - // check to see if this is a flag setting - flagsFound = findFlag(item); - for (var idx = 0; idx < flagsFound.length; ++idx) { - var flag = flagsFound[idx]; - flagOccurrences[flag] = 'flag' + flagCounter; - if (inline) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", "flag" + flagCounter); - commentHead.insertBefore(anchor, commentHead.firstChild); - } else { - userPrefix += ''; - } - ++flagCounter; - } - - var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); - if (inline) { - for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", attachmentFlagAnchors[idx]); - commentHead.insertBefore(anchor, commentHead.firstChild); - } - } else { - userPrefix += attachmentFlagAnchors.map(function(name) '').join(""); - } - - var ccOnly = (trimContent(item[2]) == 'CC'); - var ccPrefix = ccOnly ? '' : - '', - ccSuffix = ''; - var html = userPrefix + - ccPrefix + - transformType(trimContent(item[2]), d, trimContent(item[3]), - trimContent(item[4])) + ": " + - formatTransition(trimContent(item[3]), trimContent(item[4]), - trimContent(item[2]), d, iframe.contentDocument); - - var nextItemsCount = item[0].rowSpan; - for (var k = 1; k < nextItemsCount; ++k) { - ccOnly = false; - item = historyItems[++i].querySelectorAll("td") - ccPrefix = (trimContent(item[0]) == 'CC') ? - '' : ''; - // avoid showing a trailing semicolon if the previous entry - // wasn't a CC and this one is - var prefix = ccSuffix + ccPrefix; - // check to see if this is a flag setting - flagsFound = findFlag(item); - for (var idx = 0; idx < flagsFound.length; ++idx) { - var flag = flagsFound[idx]; - flagOccurrences[flag] = 'flag' + flagCounter; - if (inline) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", "flag" + flagCounter); - commentHead.insertBefore(anchor, commentHead.firstChild); - } else { - prefix += ''; - } - ++flagCounter; - } - - var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); - if (inline) { - for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", attachmentFlagAnchors[idx]); - commentHead.insertBefore(anchor, commentHead.firstChild); - } - } else { - prefix += attachmentFlagAnchors.map(function(name) '').join(""); - } - - html += prefix + - transformType(trimContent(item[0]), d, trimContent(item[1]), - trimContent(item[2])) + ": " + - formatTransition(trimContent(item[1]), trimContent(item[2]), - trimContent(item[0]), d, iframe.contentDocument); - } - html += ccSuffix; - if (ccOnly) { - html = '
    ' + html + '
    '; - } else { - html = '
    ' + html + '
    '; - } - currentDiv.innerHTML += html; - break; - } - } - - handleEmptyCollapsedBoxes(d); - - // Set the latest flag links if necessary - for (var flagName in flagOccurrences) { - flags[flagName].innerHTML = '' - + flags[flagName].innerHTML + ''; - } - - AttachmentFlagHandler.setupLinks(d); - },true); - d.body.appendChild(iframe); - - tbplbotSpamCollapser(d); -} - -// =================================================== - -var TransformValues = { - linkifyURLs: function (str) { - return str.replace(/((https?|ftp)\:\/\/[\S]+)/g, '$1'); - }, - linkifyBugAndCommentNumbers: function (str) { - return str.replace(/(bug )(\d+) (comment )(\d+)/gi, '$1\n$2 $3\n$4'); - }, - linkifyCommentNumbers: function (str) { - return str.replace(/(comment (\d+))/gi, '$1'); - }, - linkifyBugNumbers: function (str) { - return str.replace(/(bug (\d+))/gi, '$1'); - }, - linkifyDependencies: function (str, type, doc, histDoc) { - switch (type) { - case "Blocks": - case "Depends on": - case "Duplicate": - str = str.replace(/\d+/g, function(str) { - var link = histDoc.querySelector("a[href='show_bug.cgi?id=" + str + "']"); - if (link) { - var class_ = ''; - if (/bz_closed/i.test(link.className)) { - class_ += 'bz_closed '; - } else if (/bztw_unconfirmed/i.test(link.className)) { - class_ += 'bztw_unconfirmed '; - } - var parent = link.parentNode; - if (parent) { - if (parent.tagName.toLowerCase() == "i") { - class_ += 'bztw_unconfirmed '; - } - if (/bz_closed/i.test(parent.className)) { - class_ += 'bz_closed '; - } - } - str = applyClass(class_, - '' + htmlEncode(str) + ''); - } - return str; - }); - } - return str; - } -}; - -// =============================================================================== - -function transform(str, type, doc, histDoc) { - for (var funcname in TransformValues) { - var func = TransformValues[funcname]; - str = func.call(null, str, type, doc, histDoc); - } - return str -} - -var TransformTypes = { - linkifyAttachments: function (str, doc) { - return str.replace(/(Attachment #(\d+))/g, function (str, x, id) { - var link = doc.querySelector("a[href='attachment.cgi?id=" + id + "']"); - if (link) { - var class_ = ''; - if (/bz_obsolete/i.test(link.className)) { - class_ += 'bz_obsolete '; - } - var parent = link.parentNode; - if (parent && /bz_obsolete/i.test(parent.className)) { - class_ += 'bz_obsolete '; - } - if (link.querySelector(".bz_obsolete")) { - class_ += 'bz_obsolete '; - } - str = applyClass(class_, - '' + htmlEncode(str) + ''); - } - return str; - }); - }, - changeDependencyLinkTitles: function (str, doc, old, new_) { - switch (str) { - case "Blocks": - case "Depends on": - if (old.length && !new_.length) { // if the dependency was removed - str = "No longer " + str[0].toLowerCase() + str.substr(1); - } - break; - } - return str; - } -}; - -// ======================================================================= - -function transformType(str, doc, old, new_) { - for (var funcname in TransformTypes) { - var func = TransformTypes[funcname]; - str = func.call(null, str, doc, old, new_); - } - return str; -} - -// new is a keyword, which makes this function uglier than I'd like -function formatTransition(old, new_, type, doc, histDoc) { - if (old.length) { - old = transform(htmlEncode(old), type, doc, histDoc); - var setOldStyle = true; - switch (type) { - case "Blocks": - case "Depends on": - setOldStyle = false; - break; - } - if (setOldStyle) { - old = '' + old + ''; - } - } - if (new_.length) { - new_ = '' + transform(htmlEncode(new_), type, doc, histDoc) + ''; - } - var mid = ''; - if (old.length && new_.length) { - mid = ' '; - } - return old + mid + new_; -} - -// ========================================================================= - -function trimContent(el) { - return el.textContent.trim(); -} - -function AttachmentFlag(flag) { - for (var name in flag) - this[name] = flag[name]; -} -AttachmentFlag.prototype = { - equals: function(flag) { - if (this.type != flag.type || - this.name != flag.name || - this.setter != flag.setter || - ("requestee" in this && !("requestee" in flag)) || - ("requestee" in flag && !("requestee" in this))) - return false; - return this.requestee == flag.requestee; - } -}; - -var reAttachmentDiff = /attachment\.cgi\?id=(\d+)&action=diff$/i; -var reviewBoardUrlBase = "http://reviews.visophyte.org/"; - -// =============================================================================== - -/** - * Whenever we find a patch with a diff, insert an additional link to asuth's - * review board magic. - */ -function attachmentDiffLinkify(doc) { - var bug_id = getBugNo(doc); - - var table = doc.getElementById("attachment_table"); - if (!table) - return; - var rows = table.querySelectorAll("tr"); - for (var i = 0; i < rows.length; ++i) { - var item = rows[i].querySelectorAll("td"); - if (item.length != 3) - continue; - // get the ID of the attachment - var links = item[2].querySelectorAll("a"); - if (links.length != 2) - continue; - var match = reAttachmentDiff.exec(links[1].href); - if (match) { - var attach_id = match[1]; - var parentNode = links[1].parentNode; - parentNode.appendChild(doc.createTextNode(" | ")); - var linkNode = doc.createElement("a"); - linkNode.href = reviewBoardUrlBase + "r/bzpatch/bug" + bug_id + "/attach" + attach_id + "/"; - linkNode.textContent = "Review"; - parentNode.appendChild(linkNode); - } - } -} - -function quicksearchHandler(doc) { - var win = doc.defaultView; - var match = /quicksearch=([^&]+)/i.exec(win.location.search); - if (match) { - var quicksearch = unescape(match[1].replace('+', ' ', 'g')); - var quicksearchBox = doc.querySelectorAll("input[name=quicksearch]"); - if (quicksearchBox) { - for (var i = 0; i < quicksearchBox.length; ++i) { - quicksearchBox[i].value = quicksearch; - } - } - } -} - -function AttachmentFlagHandlerCtor() { - this._db = {}; - this._interestingFlags = {}; -} -AttachmentFlagHandlerCtor.prototype = { - determineInterestingFlags: function (doc) { - var table = doc.getElementById("attachment_table"); - if (!table) - return; - var rows = table.querySelectorAll("tr"); - for (var i = 0; i < rows.length; ++i) { - var item = rows[i].querySelectorAll("td"); - if (item.length != 3 || - item[1].className.indexOf("bz_attach_flags") < 0 || - trimContent(item[1]) == "no flags") - continue; - // get the ID of the attachment - var link = item[0].querySelector("a"); - if (!link) - continue; - var match = this._reAttachmentHref.exec(link.href); - if (match) { - var attachmentID = match[1]; - if (!(attachmentID in this._interestingFlags)) { - this._interestingFlags[attachmentID] = []; - } - var text = ""; - var previousText = ""; - var previousEl = null; - for (var el = item[1].firstChild; el.nextSibling; el = el.nextSibling) { - var thisText = trimContent(el).replace('\u2011', '-', 'g'); - text += thisText; - if (this._reParsePartToLinkify.test(thisText)) { - previousText = thisText; - previousEl = el; - } - if (el.nodeType != el.ELEMENT_NODE || - el.localName.toLowerCase() != "br") - continue; - match = this._reParseInterestingFlag.exec(text); - if (match) { - var flag = {}; - flag.setter = match[1]; - flag.name = match[2]; - if (match[4] == "+" || match[4] == "-") { - flag.type = match[4]; - } else { - flag.type = "?"; - if (match[7]) { - flag.requestee = match[7]; - } - } - - // always show the obsolete attachments with a + flag - if (flag.type == "+") { - var parent = link.parentNode; - while (parent) { - if (parent.tagName.toLowerCase() == "tr") { - if (/bz_tr_obsolete/i.test(parent.className)) { - parent.className += " bztw_plusflag"; - } - break; - } - parent = parent.parentNode; - } - } - - // try to put the flag name and type part in a span - // which we will - // use in setupLinks to inject links into. - match = this._reLinkifyInterestingFlag.exec(previousText); - if (match) { - previousEl.textContent = match[1]; - if (match[3]) { - var textNode = doc.createTextNode(match[3]); - previousEl.parentNode.insertBefore(textNode, previousEl.nextSibling); - } - var span = doc.createElement("span"); - span.textContent = match[2]; - previousEl.parentNode.insertBefore(span, previousEl.nextSibling); - - flag.placeholder = span; - } - - this._interestingFlags[attachmentID].push(new AttachmentFlag(flag)); - } - text = ""; - previousText = ""; - previousEl = null; - } - } - } - }, - handleItem: function (name, item) { - var anchorsCreated = []; - var base = item[4] ? 2 : 0; - var what = trimContent(item[base]); - var match = this._reAttachmentFlagName.exec(what); - if (match) { - var id = match[1]; - if (!(id in this._db)) { - this._db[id] = []; - } - name = name.split('@')[0]; // convert the name to the fraction - // before the @ - var added = this._parseData(name, trimContent(item[base + 2])); - for (var i = 0; i < added.length; ++i) { - var flag = added[i]; - if (!(id in this._interestingFlags)) - continue; - for (var j = 0; j < this._interestingFlags[id].length; ++j) { - // Take care to not assign an anchor to a flag which already has one - if (flag.equals(this._interestingFlags[id][j]) && - !("anchor" in this._interestingFlags[id][j])) { - // found an interesting flag - this._interestingFlags[id][j].anchor = this.anchorName; - anchorsCreated.push(this.anchorName); - this._counter++; - break; - } - } - } - } - return anchorsCreated; - }, - setupLinks: function (doc) { - for (var id in this._interestingFlags) { - for (var i = 0; i < this._interestingFlags[id].length; ++i) { - var flag = this._interestingFlags[id][i]; - if ("placeholder" in flag && - "anchor" in flag) { - var link = doc.createElement("a"); - link.href = "#" + flag.anchor; - link.textContent = flag.placeholder.textContent; - flag.placeholder.replaceChild(link, flag.placeholder.firstChild); - } - } - } - }, - _parseData: function (name, str) { - var items = str.replace('\u2011', '-', 'g').split(', '), flags = []; - for (var i = 0; i < items.length; ++i) { - if (!items[i].length) - continue; - - var match = this._reParseRequest.exec(items[i]); - if (match) { - var flag = {}; - flag.name = match[1]; - flag.setter = name; - if (match[4]) { - flag.requestee = match[4]; - } - flag.type = match[2]; - flags.push(new AttachmentFlag(flag)); - } - } - return flags; - }, - _counter: 1, - get anchorName() { - return "attachflag" + this._counter; - }, - _reParseRequest: /^(.+)([\?\-\+])(\((.+)@.+\))?$/, - _reParsePartToLinkify: /^\s*:\s+.+[\-\+\?](\s*\()?\s*$/, - _reParseInterestingFlag: /^(.+):\s+(.+)(([\-\+])|\?(\s+(\((.+)\)))?)$/, - _reLinkifyInterestingFlag: /^(\s*:\s+)(.+[\-\+\?])(\s*\(\s*)?$/, - _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i, - _reAttachmentFlagName: /^Attachment\s+#(\d+)\s+Flags$/i -}; - -function CheckinCommentCtor() { - this.bugNumber = null; - this.summarySpan = null; - this.checkinFlags = ""; -} -CheckinCommentCtor.prototype = { - initialize: function(doc, flags) { - this.bugNumber = getBugNo(doc); - var summarySpan = doc.getElementById("short_desc_nonedit_display"); - if (summarySpan) { - this.summary = summarySpan.textContent; - } - var checkinFlagsMap = {}; - for (var id in flags) { - for (var i = 0; i < flags[id].length; ++i) { - var flag = flags[id][i]; - if (flag.type == "+") { - var name = flag.name; - if (name == "review") { - name = "r"; - } else if (name == "superreview") { - name = "sr"; - } else if (name == "ui-review") { - name = "ui-r"; - } else if (name == "feedback") { - name = "f"; - } - if (!(name in checkinFlagsMap)) { - checkinFlagsMap[name] = {}; - } - checkinFlagsMap[name][flag.setter]++; - } - } - } - var flagsOrdered = []; - for (var name in checkinFlagsMap) { - flagsOrdered.push(name); - } - flagsOrdered.sort(function (a, b) { - function convertToNumber(x) { - switch (x) { - case "f": - return -4; - case "r": - return -3; - case "sr": - return -2; - case "ui-r": - return -1; - default: - return 0; - } - } - var an = convertToNumber(a); - var bn = convertToNumber(b); - if (an == 0 && bn == 0) { - return a < b ? -1 : (a = b ? 0 : 1); - } else { - return an - bn; - } - }); - var checkinFlags = []; - for (var i = 0; i < flagsOrdered.length; ++i) { - var name = flagsOrdered[i]; - var flag = name + "="; - var setters = []; - for (var setter in checkinFlagsMap[name]) { - setters.push(setter); - } - flag += setters.join(","); - checkinFlags.push(flag); - } - this.checkinFlags = checkinFlags.join(" "); - if (this.isValid()) { - var div = doc.createElement("div"); - div.setAttribute("style", "display: none;"); - div.id = "__bz_tw_checkin_comment"; - div.appendChild(doc.createTextNode(this.toString())); - doc.body.appendChild(div); - } - }, - isValid: function() { - return this.bugNumber != null && - this.summary != null; - }, - toString: function() { - if (!this.isValid()) { - return ""; - } - var message = "Bug " + this.bugNumber + " - " + this.summary; - if (this.checkinFlags.length) { - message += "; " + this.checkinFlags; - } - return message; - } -}; - -function DataStoreCtor(doc) { - this.storage = doc.defaultView.localStorage; - this.data = {}; - this.bugNumber = null; - function visualizeStoredData() { - var data = ""; - for (var i = 0; i < window.localStorage.length; ++i) { - var key = window.localStorage.key(i); - data += key + ": " + JSON.parse(window.localStorage.getItem(key).toString()).toSource() + "\n"; - } - open("data:text/html,
    " + escape(htmlEncode(data)) + "
    "); - } - function clearStoredData() { - var count = window.localStorage.length; - if (count > 0) { - if (window.confirm("You currently have data stored for " + count + " bugs.\n\n" + - "Are you sure you want to clear this data? This action cannot be undone.")) { - window.localStorage.clear(); - } - } else { - alert("You don't have any data stored about your bugs"); - } - } - var script = doc.createElement("script"); - script.appendChild(doc.createTextNode(visualizeStoredData.toSource() + - clearStoredData.toSource() + - htmlEncode.toSource())); - doc.body.appendChild(script); - this.initialize(doc); -} - -DataStoreCtor.prototype = { - initialize: function(doc) { - this.bugNumber = getBugNo(doc); - var data = this._ensureEntry(this.bugNumber, this.data); - // last visited date - data.visitedTime = (new Date()).getTime(); - // last comment count - data.commentCount = doc.querySelectorAll(".bz_comment").length; - // last status of bug flags - var flags = this._ensureEntry("flags", data); - var flagRows = doc.querySelectorAll("#flags tr"); - for (var i = 0; i < flagRows.length; ++i) { - var flagCols = flagRows[i].querySelectorAll("td"); - if (flagCols.length != 3) { - continue; - } - var flagName = trimContent(flagCols[1]); - var flagValue = flagCols[2].querySelector("select"); - if (flagValue) { - flagValue = flagValue.value; - } else { - continue; - } - flags[flagName] = flagValue; - } - flagRows = doc.querySelectorAll(".field_label[id^=field_label_cf_]"); - for (var i = 0; i < flagRows.length; ++i) { - var flagName = trimContent(flagRows[i]).replace(/:$/, ""); - var flagValue = flagRows[i].parentNode.querySelector("select"); - if (flagValue) { - flagValue = flagValue.value; - } else { - continue; - } - flags[flagName] = flagValue; - } - // last attachments - var attachmentTable = doc.getElementById("attachment_table"); - var attachmentRows = attachmentTable.querySelectorAll("tr"); - for (var i = 0; i < attachmentRows.length; ++i) { - var attachmentCells = attachmentRows[i].querySelectorAll("td"); - if (attachmentCells.length != 3) { - continue; - } - var link = attachmentCells[0].querySelector("a"); - var match = this._reAttachmentHref.exec(link.href); - if (match) { - var attachmentID = match[1]; - var attachment = this._ensureEntry("attachments", data); - var attachmentFlags = this._ensureArray(attachmentID, attachment); - for (var el = attachmentCells[1].firstChild; el.nextSibling; el = el.nextSibling) { - if (el.nodeType != el.TEXT_NODE) { - continue; - } - var text = trimContent(el); - if (!text) { - continue; - } - match = this._reParseInterestingFlag.exec(text); - if (match) { - var flag = {}; - flag.setter = match[1]; - flag.name = match[2]; - if (match[4] == "+" || match[4] == "-") { - flag.type = match[4]; - } else { - flag.type = "?"; - if (match[7]) { - flag.requestee = match[7]; - } - } - attachmentFlags.push(flag); - } - } - } - } - // Write data to storage - for (var key in this.data) { - this._ensure(key, this.storage, JSON.stringify(this.data[key])); - } - }, - _ensure: function(entry, obj, val) { - if (obj.toString().indexOf("[object Storage") >= 0) { - obj.setItem(entry, val); - } else { - if (typeof obj[entry] == "undefined") - obj[entry] = val; - return obj[entry]; - } - }, - _ensureEntry: function(entry, obj) { - return this._ensure(entry, obj, {}); - }, - _ensureArray: function(entry, obj) { - return this._ensure(entry, obj, []); - }, - _reParseInterestingFlag: /^(.+):\s+(.+)(([\-\+])|\?(\s+(\((.+)\)))?)$/, - _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i -}; - - -function getUserName(doc) { - var links = doc.querySelectorAll("#header .links li"); - var last = links[links.length - 1]; - if (last.innerHTML.indexOf("logout") >= 0) { - return trimContent(last.lastChild); - } - return null; -} - -function handleEmptyCollapsedBoxes(doc) { - // first, try to get the display style of a CC field (any would do) - var historyBoxes = doc.querySelectorAll(".bztw_history"); - for (var i = 0; i < historyBoxes.length; ++i) { - var box = historyBoxes[i]; - for (var j = 0; j < box.childNodes.length; ++j) { - var child = box.childNodes[j], found = true; - if (child.nodeType != child.ELEMENT_NODE) - continue; - if (child.className == "sep") { - // separators are insignificant - continue; - } else if (!/bztw_cc/.test(child.className)) { - found = false; - break; - } - } - if (found) { - box.className += " bztw_cc"; - } - } -} - -function applyClass(class_, html) { - return '' + html + ''; -} - -function htmlEncode(str) { - return str.replace('&', '&', 'g') - .replace('<', '<', 'g') - .replace('>', '>', 'g') - .replace('"', '"', 'g'); -} - -function tbplbotSpamCollapser(d) { - var collapseExpandBox = d.querySelector(".bz_collapse_expand_comments"); - if (!collapseExpandBox) { - return; - } - var a = d.createElement("a"); - a.href = "#"; - a.addEventListener("click", function(e) { - e.preventDefault(); - var win = d.defaultView; - var comments = d.querySelectorAll(".bz_comment"); - for (var i = 0; i < comments.length; ++i) { - var comment = comments[i]; - try { - if (comment.querySelector(".bz_comment_user a.email").href.substr(7) == - "tbplbot@gmail.com") { - win.collapse_comment(comment.querySelector(".bz_collapse_comment"), - comment.querySelector(".bz_comment_text")); - } - } catch (e) { - continue; - } - } - return false; - }, false); - a.appendChild(d.createTextNode("Collapse All tbplbot Comments")); - var li = d.createElement("li"); - li.appendChild(a); - collapseExpandBox.appendChild(li); -} - -tweakBugzilla(document); diff --git a/data/lib/cc-context.js b/data/lib/cc-context.js deleted file mode 100644 index 81b0a2d..0000000 --- a/data/lib/cc-context.js +++ /dev/null @@ -1,8 +0,0 @@ -self.on('click', function(node, data) { - var style = document.getElementById("bztw_cc"); - style.disabled = !style.disabled; -}); - -self.on('context', function(node) { - return onBugzillaPage(document.URL); -}); diff --git a/data/lib/checkin-context.js b/data/lib/checkin-context.js deleted file mode 100644 index 0ccec0c..0000000 --- a/data/lib/checkin-context.js +++ /dev/null @@ -1,13 +0,0 @@ -self.on('click', function(node, data) { - var message = document - .getElementById("__bz_tw_checkin_comment"); - self.postMessage(message.textContent); -}); - -self.on('context', function(node) { - if (!onBugzillaPage(document.URL)) - return false; - var message = document - .getElementById("__bz_tw_checkin_comment"); - return !!message; -}); diff --git a/data/lib/fixingAttMIME.js b/data/lib/fixingAttMIME.js deleted file mode 100644 index 365cfae..0000000 --- a/data/lib/fixingAttMIME.js +++ /dev/null @@ -1,90 +0,0 @@ -// 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 to perform - * MIME type change on. "mime_type" => "", # 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, XMLRPCURL, 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 - }); - - self.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 - * 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/preprocessDuplicates.js b/data/lib/preprocessDuplicates.js deleted file mode 100644 index d312fb9..0000000 --- a/data/lib/preprocessDuplicates.js +++ /dev/null @@ -1,132 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Bugzilla Tweaks. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Johnathan Nightingale - * Ehsan Akhgari - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -function preprocessDuplicateMarkers(mainDoc, histDoc) { - var comments = mainDoc.querySelectorAll(".bz_comment"); - var reDuplicate = /^\s*\*\*\*\s+Bug\s+(\d+)\s+has\s+been\s+marked\s+as\s+a\s+duplicate\s+of\s+this\s+bug.\s+\*\*\*\s*$/i; - var row = 0; - var rows = histDoc.querySelectorAll("#bugzilla-body tr"); - for ( var i = 1 /* comment 0 can never be a duplicate marker */; i < comments.length; ++i) { - var textHolder = comments[i] - .querySelector(".bz_comment_text"); - var match = reDuplicate.exec(trimContent(textHolder)); - if (match) { - // construct the table row to be injected in histDoc - var bugID = match[1]; - var email = comments[i] - .querySelector(".bz_comment_user .email").href - .substr(7); - var link = textHolder.querySelector("a"); - var title = link.title; - var time = trimContent(comments[i] - .querySelector(".bz_comment_time")); - var what = 'Duplicate'; - var removed = ''; - var number = trimContent( - comments[i].querySelector(".bz_comment_number")) - .replace(/[^\d]+/g, ''); - var class_ = ''; - if (/bz_closed/i.test(link.className + " " - + link.parentNode.className)) { - class_ += 'bz_closed '; - } - if (link.parentNode.tagName.toLowerCase() == 'i') { - class_ += 'bztw_unconfirmed '; - } - var added = '' + bugID - + ''; - - // inject the table row - var reachedEnd = false; - for (; row < rows.length; ++row) { - var cells = rows[row].querySelectorAll("td"); - if (cells.length != 5) - continue; - if (time > trimContent(cells[1])) { - if (row < rows.length - 1) { - continue; - } - else { - reachedEnd = true; - } - } - if (time == trimContent(cells[1])) { - cells[0].rowSpan++; - cells[1].rowSpan++; - var rowContents = [ - what, removed, added - ]; - var tr = histDoc.createElement("tr"); - rowContents.forEach(function(cellContents) { - var td = histDoc.createElement("td"); - td.innerHTML = cellContents; - tr.appendChild(td); - }); - if (row != rows.length - 1) { - rows[row].parentNode.insertBefore(tr, rows[row + 1]); - } - else { - rows[row].parentNode.appendChild(tr); - } - } - else { - var rowContents = [ - email, time, what, removed, added - ]; - var tr = histDoc.createElement("tr"); - rowContents.forEach(function(cellContents) { - var td = histDoc.createElement("td"); - td.innerHTML = cellContents; - tr.appendChild(td); - }); - if (reachedEnd) { - rows[row].parentNode.appendChild(tr); - } - else { - rows[row].parentNode.insertBefore(tr, rows[row]); - } - } - break; - } - - // remove the comment from the main doc - comments[i].parentNode.removeChild(comments[i]); - } - } -} diff --git a/data/lib/rhbzpage.js b/data/lib/rhbzpage.js deleted file mode 100644 index 752e471..0000000 --- a/data/lib/rhbzpage.js +++ /dev/null @@ -1,512 +0,0 @@ -// Released under the MIT/X11 license -// http://www.opensource.org/licenses/mit-license.php - -// For identification of graphics card -var manuChipStrs = [ [ "ATI Radeon", "ATI", "1002" ], - [ "ATI Mobility Radeon", "ATI", "1002" ], - [ "Intel Corporation", "INTEL", "8086" ], [ "NVIDIA", "NV", "10de" ] ]; - -// http://en.wikipedia.org/wiki/HSL_color_space -// when only the value of S is changed -// stupido!!! the string is value in hex for each color -var RHColor = new Color(158, 41, 43); // RGB 158, 41, 43; HSL 359, 1, 39 -var FedoraColor = new Color(0, 40, 103); // RGB 0, 40, 103; HSL 359, 1, 39 -var RawhideColor = new Color(0, 119, 0); // or "green", or RGB 0, 119, 0, or - // HSL -// 120, 0, 23 -var RHITColor = new Color(102, 0, 102); // RGB 102, 0, 102; HSL 300, 0, 20 - -// [ 126.386] (--) NOUVEAU(0): Chipset: "NVIDIA NVaf" -var logAnalyzeLogic = { - "AnalyzeInterestingLine": { - /* - * [ 126.378] (--) PCI:*(0:4:0:0) 10de:08a0:106b:00c2 rev 162, Mem @ - * 0xd2000000/16777216, \ 0xc0000000/268435456, 0xd0000000/33554432, I/O @ - * 0x00001000/128, BIOS @ 0x????????/131072 - */ - re: [ - "^(\\[[ .0-9]+\\])?\\s*\\(--\\) PCI:\\*\\([0-9:]+\\)\\s*" + - "([0-9a-f:]+).*$", - "^\\s*\\[?[ 0-9.]*\\]?\\s*\\(--\\) "+ - "([A-Za-z]+)\\([0-9]?\\): Chipset: (.*)$", - ], - func: chipsetMagic - }, - /* - * [ 126.385] (WW) Falling back to old probe method for vesa [ 126.385] (WW) - * Falling back to old probe method for fbdev [ 126.386] (--) NOUVEAU(0): - * Chipset: "NVIDIA NVaf" Backtrace: [ 33.158] Kernel command line: ro - * root=LABEL=root rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 - * SYSFONT=latarcyrheb-sun16 KEYTABLE=us drm.debug=0x04 - * - */ - "AnalyzeXorgLogBacktrace": { - re: "^\\s*(\\[[0-9 .]*\\])?\\s*(\\((EE|WW)\\)|.* [cC]hipset:.*)|\\s*(Backtrace|Kernel command line)", - func: analyzeXorg - } -}; - -var ProfessionalProducts = [ - "Red Hat Enterprise Linux", - "Red Hat Enterprise MRG" -]; - -// END OF CONSTANTS - -var btSnippet = null; - -function RHOnMessageHandler(msg) { - switch (msg.cmd) { - case "Error": - alert("Error " + msg.data); - break; - case "Unhandled": - break; - case "AddAttachmentCallback": - addAttachmentCallback(msg.data); - break; - case "FixAttachmentMIMECallback": - XMLRPCcallback(); - break; - case "AnalyzeInterestingLine": - case "AnalyzeXorgLogBacktrace": - findInterestingLine(msg.data, msg.cmd); - break; - case "queryUpstream": - queryUpstreamCallback(msg.data, constantData.queryUpstreamBug); - break; - default: - console.error("Error: unknown RPC call " + msg.toSource()); - break; - } -} - -// RHBugzillaPage object - -/** - * Auxiliary function to compute more complicated resolution - */ -function closeSomeRelease() { - // for RAWHIDE close as RAWHIDE, - // if active selection -> CURRENTRELEASE - // and put the release version to - // "Fixed in Version" textbox - // otherwise -> NEXTRELEASE - selectOption("bug_status", "CLOSED"); - var text = getSelection(); - var resolution = ""; - - if (text.length > 0) { - resolution = "CURRENTRELEASE"; - document.getElementById("cf_fixed_in").value = text; - } - else if (document.getElementById("version").value === "rawhide") { - resolution = "RAWHIDE"; - } - else { - resolution = "NEXTRELEASE"; - } - centralCommandDispatch("resolution", resolution); -} - -/** - * Additional commands specific for this subclass, overriding superclass one. - */ -function RHcentralCommandDispatch(cmdLabel, cmdParams) { - switch (cmdLabel) { - // Set up our own commands - case "closeUpstream": - addClosingUpstream(); - break; - case "computeResolution": - closeSomeRelease(); - break; - case "queryStringUpstreamBugzilla": - queryUpstream(constantData.queryUpstreamBug); - break; - case "sendBugUpstream": - sendBugUpstream(); - break; - case "markTriaged": - markBugTriaged(); - break; - case "chipMagic": - console.myDebug("cmdParams = " + cmdParams.toSource()); - fillInWhiteBoard(cmdParams); - break; - // If we don't have it here, call superclass method - default: - console.error("Unknown command:\n" + cmdLabel + "\nparameters:\n" + cmdParams); - break; - } -} - -/* === Bugzilla functions === */ - -/** - * Make it sailent that the some attachments with bad MIME type are present - * - * @param atts - * Array of attachments subarrays - * @return none - */ -function markBadAttachments(atts) { - var badMIMEArray = [ "application/octet-stream", "text/x-log", "undefined" ]; - if (!constantData.passwordState.passAvailable) { - console.myDebug("markBadAttachments : No password, no XML-RPC calls; sorry"); - return null; - } - - var badAttachments = atts.filter(function(att) { - return (isInList(att[2], badMIMEArray)); - }); - - if (badAttachments.length > 0) { - var titleElement = document. - getElementsByClassName("bz_alias_short_desc_container")[0]; - titleElement.style.backgroundColor = "olive"; - - createDeadLink("fixAllButton", "Fix all", titleElement, function() { - Array.forEach(badAttachments, function(x) { - fixAttachById(x[1], constantData.XMLRPCData[window.location.hostname].url); - }); - }, [], false, null, "f"); - badAttachments.forEach(function(x, i, a) { - addTextLink(x, constantData.XMLRPCData[window.location.hostname].url); - }); - } -} - -/** - * Open a tab in the upstream bugzilla to create a new bug - * - * @return none - */ -function sendBugUpstream() { - var urlStr = filterByRegexp(constantData.newUpstreamBug, getComponent()); - if (!urlStr) { - return null; - } - - self.postMessage(new Message("OpenBugUpstream", { - url: urlStr, - subject: document.getElementById("short_desc_nonedit_display"). - textContent.trim(), - comment: collectComments() - })); -} - -/** - * Add a link opening selected lines of Xorg.0.log - * - * @return none - */ -function addCheckXorgLogLink(attList) { - if (config.XorgLogAnalysis) { - attList.forEach(function (row) { - var elemS = row[4].getElementsByTagName("td"); - var elem = elemS[elemS.length - 1]; - createDeadLink("xorgLogAnalyzeLink", "check", elem, - analyzeXorgLog, [row[1], "AnalyzeXorgLogBacktrace"], "br"); - }); - } -} - -/** - * Given line to be parsed, find out which chipset it is and fill in the - * whiteboard - * - * @param PCIidArrObj - * object with two fields id Array manufacturer-ID and product-ID (PCI - * IDs) chipsetLine whole line containing PCI ID. - * @param driverStr - * String with the driver name - * @return None - * - */ -function fillInWhiteBoard(cardName) { - console.myDebug("fillInWhiteBoard: cardName = " + cardName); - clickMouse("editme_action"); - var titleElem = document.getElementById('short_desc'); - titleElem.value = '[' + cardName + ']\u00A0' + titleElem.value; - document.getElementById("fillin_btn").style.display = "none"; -} - -/** - * 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,paramList so that slow - * XMLHttpRequest is done in advance. - * - * @param log - * array of XorgLogAttList - * @return None - */ -function fillInChipMagic(XlogID) { - analyzeXorgLog(XlogID, "AnalyzeInterestingLine"); -} - -/** - * Creates a button to change summary by adding a graphic chip label - * - * @param Array - * with matching results of re.exec() - */ -function chipsetMagic (interestingLineArr) { - // parse Xorg.0.log - var cardStr = ""; - console.myDebug("interestingLineArr = " + interestingLineArr.toSource()); - console.myDebug("interestingLineArr[1] = " + interestingLineArr[1]); - - if (interestingLineArr.length >0) { - var interestingArray = interestingLineArr[0]; - if (interestingArray.length > 1) { - var interestingPCIID = interestingArray[2].trim().split(":"); - // If we have Chipset line, we should parse it as well and - // add to the button - if (interestingLineArr.length > 1) { - var PCIid = (interestingPCIID[0] + "," + interestingPCIID[1]). - toUpperCase(); - // Nvidia driver provides good code in the Chipset line - if (interestingPCIID[0].toLowerCase() == "10de") { - cardStr = interestingLineArr[1][2]. - replace(/\s*nvidia\s*/ig,""). - replace('"','','g'); - } else { - try { - cardStr = constantData.chipNames[PCIid][0]; - } catch (e if e instanceof TypeError) { - PCIid = PCIid.toLowerCase().replace(",",":"); - cardStr = null; - alert("PCI ID " + PCIid + " is not known!"); - self.postMessage(new Message("SetClipboard", PCIid.toString())); - } catch (e) { - throw e; - } - } - } - else { - cardStr = null; - } - - if (cardStr) { - createNewButton("short_desc_nonedit_display", false, { - "name": "Fill In", - "chipMagic": cardStr - }); - } - } - } -} - -function analyzeXorg(results) { - var innerString = ""; - - if (results.length > 0) { - results.splice(0, 1); // remove headers - results.sort(); - - results.forEach(function(lRE) { - innerString += lRE.input + "
    \n"; - }); - innerString += "----------
    \n" + - results.length + " interesting lines found."; - } - else { - innerString += "No matching lines found!"; - } - - self.postMessage(new Message("OpenStringInPanel", - '' + - "Xorg.0.log analysis
    \n" +
    -    innerString.trim() +
    -    "\n
    ")); -} - -function analyzeXorgLog(attachID, backMsg) { - self.postMessage(new Message("GetURL", { - url: "https://" + window.location.hostname + "/attachment.cgi?id=" + attachID, - backMessage: backMsg - })); -} - -function findInterestingLine(wholeLog, backMsg) { - var REstr = logAnalyzeLogic[backMsg].re; - var REarr = []; - if (typeof REstr == "string") { - REarr = [new RegExp(REstr)]; - } - else if (Array.isArray(REstr)) { - REarr = REstr.map(function (reone) { - return new RegExp(reone); - }); - } - console.myDebug("Current REs:"); - REarr.forEach(function (re) { - console.myDebug("re: " + re.source); - }); - - var results = []; - wholeLog.split("\n"). - forEach(function(line) { - REarr.forEach(function (re, reIdx) { - if (re.test(line)) { - console.myDebug("Found match on line:\n" + line); - console.myDebug("Result: " + re.exec(line).toSource()); - results.push(re.exec(line)); - } - }); - }); - console.myDebug("results = " + results.toSource()); - logAnalyzeLogic[backMsg].func(results); -} - -/** - * Add information about the upstream bug upstream, and closing it. - * - * @param evt - * Event which called this handler - * @return none - */ -function addClosingUpstream() { - var refs = document.getElementById("external_bugs_table") - .getElementsByTagName("tr"); - - // that's a bad id, if there is a one. :) - var inputBox = document.getElementById("inputbox"); - var externalBugID = 0; - var wholeURL = ""; - - // Fix missing ID on the external_id SELECT - document.getElementsByName("external_id")[0].setAttribute("id", - "external_id"); - - if (inputBox.value.match(/^http.*/)) { - externalBugID = getBugNoFromURL(inputBox.value); - if (externalBugID) { - inputBox.value = externalBugID; - } - // get bugzillaName and set the label - var bugzillaName = getBugzillaName(wholeURL.host, constantData.bugzillaLabelNames); - selectOptionByLabel("external_id", bugzillaName); - } - else if (!isNaN(inputBox.value)) { - externalBugID = parseInt(inputBox.value, 10); - var bugzillaHostname = document.getElementById("external_id").value; - wholeURL = bugzillaHostname+"show_bug.cgi?id="+externalBugID; - } - else { - // no inputBox.value -- maybe there is an external bug from - // the previous commit? - } - - // It is not good to close bug as UPSTREAM, if there is no reference - // to the upstream bug. - if ((externalBugID > 0) || (refs.length > 2)) { - var msgStr = constantData.commentStrings.sentUpstreamString; - msgStr = msgStr.replace("§§§", wholeURL); - centralCommandDispatch("comment",msgStr); - centralCommandDispatch("status", "CLOSED"); - centralCommandDispatch("resolution", "UPSTREAM"); - } - else { - console.myDebug("No external bug specified among the External References!"); - } -} - -/** - * - */ -function parseBacktrace (ret) { - var signalHandler = new RegExp("^\\s*#[0-9]*\\s*"); - var frameNo = new RegExp("^\\s*#([0-9]*)\\s"); - - var splitArray = ret.split("\n"); - var i = 0, ii = splitArray.length; - var outStr = "", curLine = "", numStr = ""; - var lineCounter = 0, endLineNo = 0; - - // TODO shouldn't we just cut off and analyze whole thread? - while (i < ii) { - if (signalHandler.test(splitArray[i])) { - break; - } - i++; - } - - if (i < ii) { - lineCounter = parseInt(frameNo.exec(splitArray[i])[1], 10); - endLineNo = lineCounter + NumberOfFrames; - curLine = splitArray[i]; - while ((lineCounter < endLineNo) && (curLine.trim().length > 0) - && (i < ii)) { - outStr += curLine + '\n'; - numStr = frameNo.exec(curLine); - if (numStr) { - lineCounter = parseInt(numStr[1], 10); - } - i++; - curLine = splitArray[i]; - } - return outStr; - } - return ""; -} - -function RHBZinit() { - // inheritance ... call superobject's constructor - var AbrtRE = new RegExp("^\\s*\\[abrt\\]"); - var btSnippet = ""; - - var chipMagicInterestingLine = ""; - - // getBadAttachments - var XorgLogAttList = []; - var XorgLogAttListIndex = 0; - var attachments = getAttachments(); - markBadAttachments(attachments); - - var parsedAttachments = attachments.filter(function (att) { - return (new RegExp(titleParsedAttachment).test(att[0])); - }); - - if (constantData.defaultAssignee) { - setDefaultAssignee(); - } - - if (constantData.xorgBugsCategories) { - var XBZlist = filterByRegexp(constantData. - xorgBugsCategories, getComponent()); - if (XBZlist) { - makeBugCategoriesList(XBZlist); - } - } - - // setup logging only when we ask for it - if (config.submitsLogging && (window.location.hostname == "bugzilla.redhat.com")) { - setUpLogging(); - } - - // Dig out backtrace protection against double-firing? - btSnippet = ""; - - var parseAbrtBacktraces = config.parseAbrtBacktraces; - if (parseAbrtBacktraces && AbrtRE.test(getSummary())) { - pasteBacktraceInComments(parsedAttachments); - } - - // Find out Xorg.0.log attachment URL - XorgLogAttList = attachments.filter(function (value) { - // Xorg.0.log must be text, otherwise we cannot parse it - return (/[xX].*log/.test(value[0]) && /text/.test(value[2])); - }); - // Just add a link to every Xorg.0.log link analyzing it. - addCheckXorgLogLink(XorgLogAttList); - - setBranding(XorgLogAttList); - - // Uncheck "set default assignee" when the assignee is changed by other means - document.getElementById("assigned_to").addEventListener("change", - function() { - changeAssignee(null); - }, false); -} diff --git a/data/lib/urltest.js b/data/lib/urltest.js deleted file mode 100644 index 609e77b..0000000 --- a/data/lib/urltest.js +++ /dev/null @@ -1,5 +0,0 @@ -function onBugzillaPage(url) { - return /https:\/\/bugzilla(-[a-zA-Z]+)*\.mozilla\.org/ - .test(url) - || /https:\/\/landfill.*\.bugzilla\.org/.test(url); -} diff --git a/data/lib/viewSource.js b/data/lib/viewSource.js deleted file mode 100644 index fd47cec..0000000 --- a/data/lib/viewSource.js +++ /dev/null @@ -1,104 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Bugzilla Tweaks. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Johnathan Nightingale - * Ehsan Akhgari - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -var reAttachmentType = /,\s+([^ )]*)[;)]/; - -function viewAttachmentSource(doc) { - function addLink(elem, title, href) { - if (elem.textContent.match(/[\S]/)) { - elem.appendChild(doc.createTextNode(" | ")); - } - var link = doc.createElement("a"); - link.href = href; - link.textContent = title; - elem.appendChild(link); - } - var table = doc.getElementById("attachment_table"); - if (!table) - return; - var rows = table.querySelectorAll("tr"); - for ( var i = 0; i < rows.length; ++i) { - var items = rows[i].querySelectorAll("td"); - if (items.length != 3) - continue; - var links = items[0].querySelectorAll("a"); - if (links.length == 0) - continue; - var attachHref = links[0].href; - // get the type of the attachment - var span = items[0].querySelector(".bz_attach_extra_info"); - if (!span) - continue; - var typeName = null; - try { - // Match mime type followed by ";" (charset) or ")" (no charset) - typeName = span.textContent.match(reAttachmentType)[1]; - typeName = typeName.split(";")[0]; // ignore charset following type - } - catch (e) { - } - if (typeName == "application/java-archive" - || typeName == "application/x-jar") { - // Due to the fix for bug 369814, only zip files with this special - // mime type can be used with the jar: protocol. - // http://hg.mozilla.org/mozilla-central/rev/be54f6bb9e1e - addLink(items[2], "JAR Contents", "jar:" + attachHref - + "!/"); - // https://bugzilla.mozilla.org/show_bug.cgi?id=369814#c5 has more - // possible mime types for zips? - } - else if (typeName == "application/zip" - || typeName == "application/x-zip-compressed" - || typeName == "application/x-xpinstall") { - addLink(items[2], "Static ZIP Contents", "jar:" - + attachHref + "!/"); - } - else if (typeName != "text/plain" && typeName != "patch" && - // Other types that Gecko displays like text/plain - // http://mxr.mozilla.org/mozilla-central/source/parser/htmlparser/public/nsIParser.h - typeName != "text/css" && typeName != "text/javascript" - && typeName != "text/ecmascript" - && typeName != "application/javascript" - && typeName != "application/ecmascript" - && typeName != "application/x-javascript" && - // Binary image types for which the "source" is not useful - typeName != "image/gif" && typeName != "image/png" - && typeName != "image/jpeg") { - addLink(items[2], "Source", "view-source:" + attachHref); - } - } -} diff --git a/data/lib/xorgBugCategories.js b/data/lib/xorgBugCategories.js deleted file mode 100644 index 3357ed7..0000000 --- a/data/lib/xorgBugCategories.js +++ /dev/null @@ -1,74 +0,0 @@ -// Released under the MIT/X11 license -// http://www.opensource.org/licenses/mit-license.php -"use strict"; - -/** - * Returns true if the bug is in a good shape - * - * @return Boolean if the bug is either not in the category where we care about - * it (i.e., we don't have set up categories for this component) or if - * it is in the concerned categories, then it has a category recorded in - * the whiteboard input box. - * - */ -function hasXorgBugsCategory() { - var catRE = /\s*\[cat:.*?\]\s*/; // RE for testing whether - // there is already category tag in the Whiteboard - - var isXOrgBug = filterByRegexp( - constantData.xorgBugsCategories, getComponent()); - var whiteboardContent = document - .getElementById("status_whiteboard").value; - - if (isXOrgBug) { // is it XOR? - return catRE.test(whiteboardContent); - } - else { - return true; - } -} - -/** - * Create a category list to the upper toolbar - */ -function makeBugCategoriesList(catList) { - var catRE = /\s*\[cat:.*?\]\s*/; // RE for testing whether - // there is already category tag in the Whiteboard - - // Create with s for each category one - if (catList) { - catList.forEach(function(cat) { - optionElement = document.createElement("option"); - optionElement.value = cat; - optionElement.setAttribute("id", "catId_" - + cat.replace(" ", "").toLowerCase()); - optionElement.appendChild(document.createTextNode(cat)); - categoryList.appendChild(optionElement); - }); - } - - categoryList.addEventListener("change", function(evt) { - var selectedCategory = "[cat:" + this.value + "]"; - var whiteboardElement = document - .getElementById("status_whiteboard"); - - if (hasXorgBugsCategory()) { - whiteboardElement.value = whiteboardElement.value.replace( - catRE, ""); - } - addStuffToTextBox("status_whiteboard", selectedCategory); - }, false); - - targetDiv.insertBefore(categoryList, targetDiv.firstChild); -} diff --git a/data/rhlib/fixingAttMIME.js b/data/rhlib/fixingAttMIME.js new file mode 100644 index 0000000..365cfae --- /dev/null +++ b/data/rhlib/fixingAttMIME.js @@ -0,0 +1,90 @@ +// 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 to perform + * MIME type change on. "mime_type" => "", # 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, XMLRPCURL, 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 + }); + + self.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 + * 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/rhlib/rhbzpage.js b/data/rhlib/rhbzpage.js new file mode 100644 index 0000000..752e471 --- /dev/null +++ b/data/rhlib/rhbzpage.js @@ -0,0 +1,512 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php + +// For identification of graphics card +var manuChipStrs = [ [ "ATI Radeon", "ATI", "1002" ], + [ "ATI Mobility Radeon", "ATI", "1002" ], + [ "Intel Corporation", "INTEL", "8086" ], [ "NVIDIA", "NV", "10de" ] ]; + +// http://en.wikipedia.org/wiki/HSL_color_space +// when only the value of S is changed +// stupido!!! the string is value in hex for each color +var RHColor = new Color(158, 41, 43); // RGB 158, 41, 43; HSL 359, 1, 39 +var FedoraColor = new Color(0, 40, 103); // RGB 0, 40, 103; HSL 359, 1, 39 +var RawhideColor = new Color(0, 119, 0); // or "green", or RGB 0, 119, 0, or + // HSL +// 120, 0, 23 +var RHITColor = new Color(102, 0, 102); // RGB 102, 0, 102; HSL 300, 0, 20 + +// [ 126.386] (--) NOUVEAU(0): Chipset: "NVIDIA NVaf" +var logAnalyzeLogic = { + "AnalyzeInterestingLine": { + /* + * [ 126.378] (--) PCI:*(0:4:0:0) 10de:08a0:106b:00c2 rev 162, Mem @ + * 0xd2000000/16777216, \ 0xc0000000/268435456, 0xd0000000/33554432, I/O @ + * 0x00001000/128, BIOS @ 0x????????/131072 + */ + re: [ + "^(\\[[ .0-9]+\\])?\\s*\\(--\\) PCI:\\*\\([0-9:]+\\)\\s*" + + "([0-9a-f:]+).*$", + "^\\s*\\[?[ 0-9.]*\\]?\\s*\\(--\\) "+ + "([A-Za-z]+)\\([0-9]?\\): Chipset: (.*)$", + ], + func: chipsetMagic + }, + /* + * [ 126.385] (WW) Falling back to old probe method for vesa [ 126.385] (WW) + * Falling back to old probe method for fbdev [ 126.386] (--) NOUVEAU(0): + * Chipset: "NVIDIA NVaf" Backtrace: [ 33.158] Kernel command line: ro + * root=LABEL=root rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 + * SYSFONT=latarcyrheb-sun16 KEYTABLE=us drm.debug=0x04 + * + */ + "AnalyzeXorgLogBacktrace": { + re: "^\\s*(\\[[0-9 .]*\\])?\\s*(\\((EE|WW)\\)|.* [cC]hipset:.*)|\\s*(Backtrace|Kernel command line)", + func: analyzeXorg + } +}; + +var ProfessionalProducts = [ + "Red Hat Enterprise Linux", + "Red Hat Enterprise MRG" +]; + +// END OF CONSTANTS + +var btSnippet = null; + +function RHOnMessageHandler(msg) { + switch (msg.cmd) { + case "Error": + alert("Error " + msg.data); + break; + case "Unhandled": + break; + case "AddAttachmentCallback": + addAttachmentCallback(msg.data); + break; + case "FixAttachmentMIMECallback": + XMLRPCcallback(); + break; + case "AnalyzeInterestingLine": + case "AnalyzeXorgLogBacktrace": + findInterestingLine(msg.data, msg.cmd); + break; + case "queryUpstream": + queryUpstreamCallback(msg.data, constantData.queryUpstreamBug); + break; + default: + console.error("Error: unknown RPC call " + msg.toSource()); + break; + } +} + +// RHBugzillaPage object + +/** + * Auxiliary function to compute more complicated resolution + */ +function closeSomeRelease() { + // for RAWHIDE close as RAWHIDE, + // if active selection -> CURRENTRELEASE + // and put the release version to + // "Fixed in Version" textbox + // otherwise -> NEXTRELEASE + selectOption("bug_status", "CLOSED"); + var text = getSelection(); + var resolution = ""; + + if (text.length > 0) { + resolution = "CURRENTRELEASE"; + document.getElementById("cf_fixed_in").value = text; + } + else if (document.getElementById("version").value === "rawhide") { + resolution = "RAWHIDE"; + } + else { + resolution = "NEXTRELEASE"; + } + centralCommandDispatch("resolution", resolution); +} + +/** + * Additional commands specific for this subclass, overriding superclass one. + */ +function RHcentralCommandDispatch(cmdLabel, cmdParams) { + switch (cmdLabel) { + // Set up our own commands + case "closeUpstream": + addClosingUpstream(); + break; + case "computeResolution": + closeSomeRelease(); + break; + case "queryStringUpstreamBugzilla": + queryUpstream(constantData.queryUpstreamBug); + break; + case "sendBugUpstream": + sendBugUpstream(); + break; + case "markTriaged": + markBugTriaged(); + break; + case "chipMagic": + console.myDebug("cmdParams = " + cmdParams.toSource()); + fillInWhiteBoard(cmdParams); + break; + // If we don't have it here, call superclass method + default: + console.error("Unknown command:\n" + cmdLabel + "\nparameters:\n" + cmdParams); + break; + } +} + +/* === Bugzilla functions === */ + +/** + * Make it sailent that the some attachments with bad MIME type are present + * + * @param atts + * Array of attachments subarrays + * @return none + */ +function markBadAttachments(atts) { + var badMIMEArray = [ "application/octet-stream", "text/x-log", "undefined" ]; + if (!constantData.passwordState.passAvailable) { + console.myDebug("markBadAttachments : No password, no XML-RPC calls; sorry"); + return null; + } + + var badAttachments = atts.filter(function(att) { + return (isInList(att[2], badMIMEArray)); + }); + + if (badAttachments.length > 0) { + var titleElement = document. + getElementsByClassName("bz_alias_short_desc_container")[0]; + titleElement.style.backgroundColor = "olive"; + + createDeadLink("fixAllButton", "Fix all", titleElement, function() { + Array.forEach(badAttachments, function(x) { + fixAttachById(x[1], constantData.XMLRPCData[window.location.hostname].url); + }); + }, [], false, null, "f"); + badAttachments.forEach(function(x, i, a) { + addTextLink(x, constantData.XMLRPCData[window.location.hostname].url); + }); + } +} + +/** + * Open a tab in the upstream bugzilla to create a new bug + * + * @return none + */ +function sendBugUpstream() { + var urlStr = filterByRegexp(constantData.newUpstreamBug, getComponent()); + if (!urlStr) { + return null; + } + + self.postMessage(new Message("OpenBugUpstream", { + url: urlStr, + subject: document.getElementById("short_desc_nonedit_display"). + textContent.trim(), + comment: collectComments() + })); +} + +/** + * Add a link opening selected lines of Xorg.0.log + * + * @return none + */ +function addCheckXorgLogLink(attList) { + if (config.XorgLogAnalysis) { + attList.forEach(function (row) { + var elemS = row[4].getElementsByTagName("td"); + var elem = elemS[elemS.length - 1]; + createDeadLink("xorgLogAnalyzeLink", "check", elem, + analyzeXorgLog, [row[1], "AnalyzeXorgLogBacktrace"], "br"); + }); + } +} + +/** + * Given line to be parsed, find out which chipset it is and fill in the + * whiteboard + * + * @param PCIidArrObj + * object with two fields id Array manufacturer-ID and product-ID (PCI + * IDs) chipsetLine whole line containing PCI ID. + * @param driverStr + * String with the driver name + * @return None + * + */ +function fillInWhiteBoard(cardName) { + console.myDebug("fillInWhiteBoard: cardName = " + cardName); + clickMouse("editme_action"); + var titleElem = document.getElementById('short_desc'); + titleElem.value = '[' + cardName + ']\u00A0' + titleElem.value; + document.getElementById("fillin_btn").style.display = "none"; +} + +/** + * 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,paramList so that slow + * XMLHttpRequest is done in advance. + * + * @param log + * array of XorgLogAttList + * @return None + */ +function fillInChipMagic(XlogID) { + analyzeXorgLog(XlogID, "AnalyzeInterestingLine"); +} + +/** + * Creates a button to change summary by adding a graphic chip label + * + * @param Array + * with matching results of re.exec() + */ +function chipsetMagic (interestingLineArr) { + // parse Xorg.0.log + var cardStr = ""; + console.myDebug("interestingLineArr = " + interestingLineArr.toSource()); + console.myDebug("interestingLineArr[1] = " + interestingLineArr[1]); + + if (interestingLineArr.length >0) { + var interestingArray = interestingLineArr[0]; + if (interestingArray.length > 1) { + var interestingPCIID = interestingArray[2].trim().split(":"); + // If we have Chipset line, we should parse it as well and + // add to the button + if (interestingLineArr.length > 1) { + var PCIid = (interestingPCIID[0] + "," + interestingPCIID[1]). + toUpperCase(); + // Nvidia driver provides good code in the Chipset line + if (interestingPCIID[0].toLowerCase() == "10de") { + cardStr = interestingLineArr[1][2]. + replace(/\s*nvidia\s*/ig,""). + replace('"','','g'); + } else { + try { + cardStr = constantData.chipNames[PCIid][0]; + } catch (e if e instanceof TypeError) { + PCIid = PCIid.toLowerCase().replace(",",":"); + cardStr = null; + alert("PCI ID " + PCIid + " is not known!"); + self.postMessage(new Message("SetClipboard", PCIid.toString())); + } catch (e) { + throw e; + } + } + } + else { + cardStr = null; + } + + if (cardStr) { + createNewButton("short_desc_nonedit_display", false, { + "name": "Fill In", + "chipMagic": cardStr + }); + } + } + } +} + +function analyzeXorg(results) { + var innerString = ""; + + if (results.length > 0) { + results.splice(0, 1); // remove headers + results.sort(); + + results.forEach(function(lRE) { + innerString += lRE.input + "
    \n"; + }); + innerString += "----------
    \n" + + results.length + " interesting lines found."; + } + else { + innerString += "No matching lines found!"; + } + + self.postMessage(new Message("OpenStringInPanel", + '' + + "Xorg.0.log analysis
    \n" +
    +    innerString.trim() +
    +    "\n
    ")); +} + +function analyzeXorgLog(attachID, backMsg) { + self.postMessage(new Message("GetURL", { + url: "https://" + window.location.hostname + "/attachment.cgi?id=" + attachID, + backMessage: backMsg + })); +} + +function findInterestingLine(wholeLog, backMsg) { + var REstr = logAnalyzeLogic[backMsg].re; + var REarr = []; + if (typeof REstr == "string") { + REarr = [new RegExp(REstr)]; + } + else if (Array.isArray(REstr)) { + REarr = REstr.map(function (reone) { + return new RegExp(reone); + }); + } + console.myDebug("Current REs:"); + REarr.forEach(function (re) { + console.myDebug("re: " + re.source); + }); + + var results = []; + wholeLog.split("\n"). + forEach(function(line) { + REarr.forEach(function (re, reIdx) { + if (re.test(line)) { + console.myDebug("Found match on line:\n" + line); + console.myDebug("Result: " + re.exec(line).toSource()); + results.push(re.exec(line)); + } + }); + }); + console.myDebug("results = " + results.toSource()); + logAnalyzeLogic[backMsg].func(results); +} + +/** + * Add information about the upstream bug upstream, and closing it. + * + * @param evt + * Event which called this handler + * @return none + */ +function addClosingUpstream() { + var refs = document.getElementById("external_bugs_table") + .getElementsByTagName("tr"); + + // that's a bad id, if there is a one. :) + var inputBox = document.getElementById("inputbox"); + var externalBugID = 0; + var wholeURL = ""; + + // Fix missing ID on the external_id SELECT + document.getElementsByName("external_id")[0].setAttribute("id", + "external_id"); + + if (inputBox.value.match(/^http.*/)) { + externalBugID = getBugNoFromURL(inputBox.value); + if (externalBugID) { + inputBox.value = externalBugID; + } + // get bugzillaName and set the label + var bugzillaName = getBugzillaName(wholeURL.host, constantData.bugzillaLabelNames); + selectOptionByLabel("external_id", bugzillaName); + } + else if (!isNaN(inputBox.value)) { + externalBugID = parseInt(inputBox.value, 10); + var bugzillaHostname = document.getElementById("external_id").value; + wholeURL = bugzillaHostname+"show_bug.cgi?id="+externalBugID; + } + else { + // no inputBox.value -- maybe there is an external bug from + // the previous commit? + } + + // It is not good to close bug as UPSTREAM, if there is no reference + // to the upstream bug. + if ((externalBugID > 0) || (refs.length > 2)) { + var msgStr = constantData.commentStrings.sentUpstreamString; + msgStr = msgStr.replace("§§§", wholeURL); + centralCommandDispatch("comment",msgStr); + centralCommandDispatch("status", "CLOSED"); + centralCommandDispatch("resolution", "UPSTREAM"); + } + else { + console.myDebug("No external bug specified among the External References!"); + } +} + +/** + * + */ +function parseBacktrace (ret) { + var signalHandler = new RegExp("^\\s*#[0-9]*\\s*"); + var frameNo = new RegExp("^\\s*#([0-9]*)\\s"); + + var splitArray = ret.split("\n"); + var i = 0, ii = splitArray.length; + var outStr = "", curLine = "", numStr = ""; + var lineCounter = 0, endLineNo = 0; + + // TODO shouldn't we just cut off and analyze whole thread? + while (i < ii) { + if (signalHandler.test(splitArray[i])) { + break; + } + i++; + } + + if (i < ii) { + lineCounter = parseInt(frameNo.exec(splitArray[i])[1], 10); + endLineNo = lineCounter + NumberOfFrames; + curLine = splitArray[i]; + while ((lineCounter < endLineNo) && (curLine.trim().length > 0) + && (i < ii)) { + outStr += curLine + '\n'; + numStr = frameNo.exec(curLine); + if (numStr) { + lineCounter = parseInt(numStr[1], 10); + } + i++; + curLine = splitArray[i]; + } + return outStr; + } + return ""; +} + +function RHBZinit() { + // inheritance ... call superobject's constructor + var AbrtRE = new RegExp("^\\s*\\[abrt\\]"); + var btSnippet = ""; + + var chipMagicInterestingLine = ""; + + // getBadAttachments + var XorgLogAttList = []; + var XorgLogAttListIndex = 0; + var attachments = getAttachments(); + markBadAttachments(attachments); + + var parsedAttachments = attachments.filter(function (att) { + return (new RegExp(titleParsedAttachment).test(att[0])); + }); + + if (constantData.defaultAssignee) { + setDefaultAssignee(); + } + + if (constantData.xorgBugsCategories) { + var XBZlist = filterByRegexp(constantData. + xorgBugsCategories, getComponent()); + if (XBZlist) { + makeBugCategoriesList(XBZlist); + } + } + + // setup logging only when we ask for it + if (config.submitsLogging && (window.location.hostname == "bugzilla.redhat.com")) { + setUpLogging(); + } + + // Dig out backtrace protection against double-firing? + btSnippet = ""; + + var parseAbrtBacktraces = config.parseAbrtBacktraces; + if (parseAbrtBacktraces && AbrtRE.test(getSummary())) { + pasteBacktraceInComments(parsedAttachments); + } + + // Find out Xorg.0.log attachment URL + XorgLogAttList = attachments.filter(function (value) { + // Xorg.0.log must be text, otherwise we cannot parse it + return (/[xX].*log/.test(value[0]) && /text/.test(value[2])); + }); + // Just add a link to every Xorg.0.log link analyzing it. + addCheckXorgLogLink(XorgLogAttList); + + setBranding(XorgLogAttList); + + // Uncheck "set default assignee" when the assignee is changed by other means + document.getElementById("assigned_to").addEventListener("change", + function() { + changeAssignee(null); + }, false); +} diff --git a/data/rhlib/xorgBugCategories.js b/data/rhlib/xorgBugCategories.js new file mode 100644 index 0000000..3357ed7 --- /dev/null +++ b/data/rhlib/xorgBugCategories.js @@ -0,0 +1,74 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php +"use strict"; + +/** + * Returns true if the bug is in a good shape + * + * @return Boolean if the bug is either not in the category where we care about + * it (i.e., we don't have set up categories for this component) or if + * it is in the concerned categories, then it has a category recorded in + * the whiteboard input box. + * + */ +function hasXorgBugsCategory() { + var catRE = /\s*\[cat:.*?\]\s*/; // RE for testing whether + // there is already category tag in the Whiteboard + + var isXOrgBug = filterByRegexp( + constantData.xorgBugsCategories, getComponent()); + var whiteboardContent = document + .getElementById("status_whiteboard").value; + + if (isXOrgBug) { // is it XOR? + return catRE.test(whiteboardContent); + } + else { + return true; + } +} + +/** + * Create a category list to the upper toolbar + */ +function makeBugCategoriesList(catList) { + var catRE = /\s*\[cat:.*?\]\s*/; // RE for testing whether + // there is already category tag in the Whiteboard + + // Create with s for each category one + if (catList) { + catList.forEach(function(cat) { + optionElement = document.createElement("option"); + optionElement.value = cat; + optionElement.setAttribute("id", "catId_" + + cat.replace(" ", "").toLowerCase()); + optionElement.appendChild(document.createTextNode(cat)); + categoryList.appendChild(optionElement); + }); + } + + categoryList.addEventListener("change", function(evt) { + var selectedCategory = "[cat:" + this.value + "]"; + var whiteboardElement = document + .getElementById("status_whiteboard"); + + if (hasXorgBugsCategory()) { + whiteboardElement.value = whiteboardElement.value.replace( + catRE, ""); + } + addStuffToTextBox("status_whiteboard", selectedCategory); + }, false); + + targetDiv.insertBefore(categoryList, targetDiv.firstChild); +} diff --git a/data/tweaks/addNewLinks.js b/data/tweaks/addNewLinks.js new file mode 100644 index 0000000..b8e7bd2 --- /dev/null +++ b/data/tweaks/addNewLinks.js @@ -0,0 +1,77 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Bugzilla Tweaks. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johnathan Nightingale + * Ehsan Akhgari + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +function addNewLinks(d) { + var product = d + .querySelector("#field_container_product option[selected]"); + var component = d.querySelector("#component option[selected]"); + + if (product) { + var label = d.getElementById('field_container_product'); + var url = 'enter_bug.cgi?product=' + + encodeURIComponent(product.value); + if (label) { + createDeadLink("file_new_bug_product", "new", label, url, + [], "parens"); + } + } + + if (product && component) { + var select = d.querySelector("select#component"); + var label = select.parentNode; + var url = 'enter_bug.cgi?product=' + + encodeURIComponent(product.value) + '&component=' + + encodeURIComponent(component.value); + if (label) { + var componentElement = document + .getElementById("bz_component_input"); + if (componentElement) { // We are in the Red Hat bugzilla + // do we have components list visible? + if (document.getElementById('bz_component_input').classList + .contains("bz_default_hidden")) { + label = document + .getElementById("bz_component_edit_container"); + } + } + else { + label = document.getElementById('component').parentNode; + } + createDeadLink("file_new_bug_component", "new", label, + url, [], "parens"); + } + } +} diff --git a/data/tweaks/bug-page-mod.js b/data/tweaks/bug-page-mod.js new file mode 100644 index 0000000..a7fb7e7 --- /dev/null +++ b/data/tweaks/bug-page-mod.js @@ -0,0 +1,1013 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Bugzilla Tweaks. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johnathan Nightingale + * Ehsan Akhgari + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +function tweakBugzilla(d) { + // run on both bugzilla.m.o and bugzilla-stage-tip.m.o + // if (!onBugzillaPage(d.URL)) + // return; + + // Put the quicksearch text in the quicksearch boxes + quicksearchHandler(d); + + if (!d.getElementById("comments")) // don't process the mid-air collision + // pages + return; + + // Make the comment box bigger ... TODO not necessary on RH BZ, but doesn't hurt + var commentBox = d.getElementById("comment"); + if (commentBox) + commentBox.rows=20; + + addNewLinks(d); + + attachmentDiffLinkify(d); + + viewAttachmentSource(d); + + // Mark up history along right hand edge + // TODO ... not sure what does this mean ... this + // element is I suppose everywhere. + var historyLink = d.querySelector("link[title='Bug Activity']"); + if (!historyLink) + return; + + // Add our own style for bugzilla-tweaks + var style = d.createElement("style"); + style.setAttribute("type", "text/css"); + style.appendChild(d.createTextNode( + ".bztw_history { border: none; font-weight: normal; width: 58em; margin-left: 5em; }" + + ".bztw_inlinehistory { font-weight: normal; width: 56em; }" + + ".bztw_history .old, .bztw_inlinehistory .old { text-decoration: line-through; }" + + ".bztw_history .sep:before { content: \" \"; }" + + ".bztw_unconfirmed { font-style: italic; }" + + "tr.bz_tr_obsolete.bztw_plusflag { display: table-row !important; }" + + '.bztw_historyitem + .bztw_historyitem:before { content: "; "; }' + )); + d.getElementsByTagName("head")[0].appendChild(style); + style = d.createElement("style"); + style.setAttribute("type", "text/css"); + style.id = "bztw_cc"; + style.appendChild(d.createTextNode( + ".bztw_cc { display: none; }" + + '.bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: ""; }' + + '.bztw_historyitem:not([class~="bztw_cc"]) ~ .bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: "; "; }' + )); + d.getElementsByTagName("head")[0].appendChild(style); + + var userNameCache = {}; + function getUserName(email) { + if (email in userNameCache) { + return userNameCache[email]; + } + var emailLink = d.querySelectorAll("a.email"); + for (var i = 0; i < emailLink.length; ++i) { + if (emailLink[i].href == "mailto:" + email) { + return userNameCache[email] = htmlEncode(trimContent(emailLink[i])); + } + } + return email; + } + + // collect the flag names + var flagNames = [], flags = {}, flagOccurrences = {}; + var flagRows = d.querySelectorAll("#flags tr"); + for (var i = 0; i < flagRows.length; ++i) { + var item = flagRows[i].querySelectorAll("td"); + if (!item[1]) + continue; + var name = trimContent(item[1]).replace('\u2011', '-', 'g'); + flagNames.push(name); + flags[name] = item[1]; + } + flagRows = d.querySelectorAll(".field_label[id^=field_label_cf_]"); + for (var i = 0; i < flagRows.length; ++i) { + var name = trimContent(flagRows[i]).replace(/\:$/, '') + .replace('\u2011', '-', 'g'); + flagNames.push(name); + flags[name] = flagRows[i]; + } + var flagCounter = 1; + + // ================================================= + function findFlag(item) { + function lookup(names) { + names = names.split(", "); + var results = []; + for (var j = 0; j < names.length; ++j) { + var name = names[j].replace('\u2011', '-', 'g'); + for (var i = 0; i < flagNames.length; ++i) { + var quotedFlagName = flagNames[i].replace('.', '\\.', 'g') + .replace('\u2011', '-', 'g'); + if ((new RegExp('^' + quotedFlagName)).test(name)) { + results.push(flagNames[i]); + break; + } + } + } + return results; + } + var base = item[4] ? 2 : 0; + // handle normal flags + if (trimContent(item[base]) == 'Flags') { + var result = lookup(trimContent(item[base + 1])). + concat(lookup(trimContent(item[base + 2]))); + return result; + } + // handle special pseudo-flags + return lookup(trimContent(item[base])); + } + + var DataStore = new DataStoreCtor(d); + + var AttachmentFlagHandler = new AttachmentFlagHandlerCtor(); + AttachmentFlagHandler.determineInterestingFlags(d); + + var CheckinComment = new CheckinCommentCtor(); + CheckinComment.initialize(d, AttachmentFlagHandler._interestingFlags); + + var iframe = d.createElement('iframe'); + iframe.src = historyLink.href; + iframe.style.display = "none"; + iframe.addEventListener("load", function() { + preprocessDuplicateMarkers(d, iframe.contentDocument); + + var historyItems = iframe.contentDocument.querySelectorAll('#bugzilla-body tr'); + var commentTimes = d.querySelectorAll('.bz_comment_time'); + + // Sometimes the history will stack several changes together, + // and we'll want to append the data from the Nth item to the + // div created in N-1 + var i=0, j=0, flagsFound; + for (; i < historyItems.length; i++) { + var item = historyItems[i].querySelectorAll("td"); + if (!item[1]) + continue; + + var reachedEnd = false; + for (; j < commentTimes.length; j++) { + if (trimContent(item[1]) > trimContent(commentTimes[j])) { + if (j < commentTimes.length - 1) { + continue; + } else { + reachedEnd = true; + } + } + + var commentHead = commentTimes[j].parentNode; + + var mainUser = commentHead.querySelector(".bz_comment_user a.email") + .href + .substr(7); + var user = trimContent(item[0]); + var mainTime = trimContent(commentTimes[j]); + var time = trimContent(item[1]); + var inline = (mainUser == user && time == mainTime); + + var currentDiv = d.createElement("div"); + var userPrefix = ''; + if (inline) { + // assume that the change was made by the same user + commentHead.appendChild(currentDiv); + currentDiv.setAttribute("class", "bztw_inlinehistory"); + } else { + // the change was made by another user + if (!reachedEnd) { + var parentDiv = commentHead.parentNode; + if (parentDiv.previousElementSibling && + parentDiv.previousElementSibling.className.indexOf("bztw_history") >= 0) { + currentDiv = parentDiv.previousElementSibling; + } else { + parentDiv.parentNode.insertBefore(currentDiv, parentDiv); + } + } else { + var parentDiv = commentHead.parentNode; + if (parentDiv.nextElementSibling && + parentDiv.nextElementSibling.className.indexOf("bztw_history") >= 0) { + currentDiv = parentDiv.nextElementSibling; + } else { + parentDiv.parentNode.appendChild(currentDiv); + } + } + currentDiv.setAttribute("class", "bz_comment bztw_history"); + userPrefix += "" + + getUserName(trimContent(item[0])) + ": "; + } + // check to see if this is a flag setting + flagsFound = findFlag(item); + for (var idx = 0; idx < flagsFound.length; ++idx) { + var flag = flagsFound[idx]; + flagOccurrences[flag] = 'flag' + flagCounter; + if (inline) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", "flag" + flagCounter); + commentHead.insertBefore(anchor, commentHead.firstChild); + } else { + userPrefix += ''; + } + ++flagCounter; + } + + var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); + if (inline) { + for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", attachmentFlagAnchors[idx]); + commentHead.insertBefore(anchor, commentHead.firstChild); + } + } else { + userPrefix += attachmentFlagAnchors.map(function(name) '').join(""); + } + + var ccOnly = (trimContent(item[2]) == 'CC'); + var ccPrefix = ccOnly ? '' : + '', + ccSuffix = ''; + var html = userPrefix + + ccPrefix + + transformType(trimContent(item[2]), d, trimContent(item[3]), + trimContent(item[4])) + ": " + + formatTransition(trimContent(item[3]), trimContent(item[4]), + trimContent(item[2]), d, iframe.contentDocument); + + var nextItemsCount = item[0].rowSpan; + for (var k = 1; k < nextItemsCount; ++k) { + ccOnly = false; + item = historyItems[++i].querySelectorAll("td") + ccPrefix = (trimContent(item[0]) == 'CC') ? + '' : ''; + // avoid showing a trailing semicolon if the previous entry + // wasn't a CC and this one is + var prefix = ccSuffix + ccPrefix; + // check to see if this is a flag setting + flagsFound = findFlag(item); + for (var idx = 0; idx < flagsFound.length; ++idx) { + var flag = flagsFound[idx]; + flagOccurrences[flag] = 'flag' + flagCounter; + if (inline) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", "flag" + flagCounter); + commentHead.insertBefore(anchor, commentHead.firstChild); + } else { + prefix += ''; + } + ++flagCounter; + } + + var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); + if (inline) { + for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", attachmentFlagAnchors[idx]); + commentHead.insertBefore(anchor, commentHead.firstChild); + } + } else { + prefix += attachmentFlagAnchors.map(function(name) '').join(""); + } + + html += prefix + + transformType(trimContent(item[0]), d, trimContent(item[1]), + trimContent(item[2])) + ": " + + formatTransition(trimContent(item[1]), trimContent(item[2]), + trimContent(item[0]), d, iframe.contentDocument); + } + html += ccSuffix; + if (ccOnly) { + html = '
    ' + html + '
    '; + } else { + html = '
    ' + html + '
    '; + } + currentDiv.innerHTML += html; + break; + } + } + + handleEmptyCollapsedBoxes(d); + + // Set the latest flag links if necessary + for (var flagName in flagOccurrences) { + flags[flagName].innerHTML = '' + + flags[flagName].innerHTML + ''; + } + + AttachmentFlagHandler.setupLinks(d); + },true); + d.body.appendChild(iframe); + + tbplbotSpamCollapser(d); +} + +// =================================================== + +var TransformValues = { + linkifyURLs: function (str) { + return str.replace(/((https?|ftp)\:\/\/[\S]+)/g, '$1'); + }, + linkifyBugAndCommentNumbers: function (str) { + return str.replace(/(bug )(\d+) (comment )(\d+)/gi, '$1\n$2 $3\n$4'); + }, + linkifyCommentNumbers: function (str) { + return str.replace(/(comment (\d+))/gi, '$1'); + }, + linkifyBugNumbers: function (str) { + return str.replace(/(bug (\d+))/gi, '$1'); + }, + linkifyDependencies: function (str, type, doc, histDoc) { + switch (type) { + case "Blocks": + case "Depends on": + case "Duplicate": + str = str.replace(/\d+/g, function(str) { + var link = histDoc.querySelector("a[href='show_bug.cgi?id=" + str + "']"); + if (link) { + var class_ = ''; + if (/bz_closed/i.test(link.className)) { + class_ += 'bz_closed '; + } else if (/bztw_unconfirmed/i.test(link.className)) { + class_ += 'bztw_unconfirmed '; + } + var parent = link.parentNode; + if (parent) { + if (parent.tagName.toLowerCase() == "i") { + class_ += 'bztw_unconfirmed '; + } + if (/bz_closed/i.test(parent.className)) { + class_ += 'bz_closed '; + } + } + str = applyClass(class_, + '' + htmlEncode(str) + ''); + } + return str; + }); + } + return str; + } +}; + +// =============================================================================== + +function transform(str, type, doc, histDoc) { + for (var funcname in TransformValues) { + var func = TransformValues[funcname]; + str = func.call(null, str, type, doc, histDoc); + } + return str +} + +var TransformTypes = { + linkifyAttachments: function (str, doc) { + return str.replace(/(Attachment #(\d+))/g, function (str, x, id) { + var link = doc.querySelector("a[href='attachment.cgi?id=" + id + "']"); + if (link) { + var class_ = ''; + if (/bz_obsolete/i.test(link.className)) { + class_ += 'bz_obsolete '; + } + var parent = link.parentNode; + if (parent && /bz_obsolete/i.test(parent.className)) { + class_ += 'bz_obsolete '; + } + if (link.querySelector(".bz_obsolete")) { + class_ += 'bz_obsolete '; + } + str = applyClass(class_, + '' + htmlEncode(str) + ''); + } + return str; + }); + }, + changeDependencyLinkTitles: function (str, doc, old, new_) { + switch (str) { + case "Blocks": + case "Depends on": + if (old.length && !new_.length) { // if the dependency was removed + str = "No longer " + str[0].toLowerCase() + str.substr(1); + } + break; + } + return str; + } +}; + +// ======================================================================= + +function transformType(str, doc, old, new_) { + for (var funcname in TransformTypes) { + var func = TransformTypes[funcname]; + str = func.call(null, str, doc, old, new_); + } + return str; +} + +// new is a keyword, which makes this function uglier than I'd like +function formatTransition(old, new_, type, doc, histDoc) { + if (old.length) { + old = transform(htmlEncode(old), type, doc, histDoc); + var setOldStyle = true; + switch (type) { + case "Blocks": + case "Depends on": + setOldStyle = false; + break; + } + if (setOldStyle) { + old = '' + old + ''; + } + } + if (new_.length) { + new_ = '' + transform(htmlEncode(new_), type, doc, histDoc) + ''; + } + var mid = ''; + if (old.length && new_.length) { + mid = ' '; + } + return old + mid + new_; +} + +// ========================================================================= + +function trimContent(el) { + return el.textContent.trim(); +} + +function AttachmentFlag(flag) { + for (var name in flag) + this[name] = flag[name]; +} +AttachmentFlag.prototype = { + equals: function(flag) { + if (this.type != flag.type || + this.name != flag.name || + this.setter != flag.setter || + ("requestee" in this && !("requestee" in flag)) || + ("requestee" in flag && !("requestee" in this))) + return false; + return this.requestee == flag.requestee; + } +}; + +var reAttachmentDiff = /attachment\.cgi\?id=(\d+)&action=diff$/i; +var reviewBoardUrlBase = "http://reviews.visophyte.org/"; + +// =============================================================================== + +/** + * Whenever we find a patch with a diff, insert an additional link to asuth's + * review board magic. + */ +function attachmentDiffLinkify(doc) { + var bug_id = getBugNo(doc); + + var table = doc.getElementById("attachment_table"); + if (!table) + return; + var rows = table.querySelectorAll("tr"); + for (var i = 0; i < rows.length; ++i) { + var item = rows[i].querySelectorAll("td"); + if (item.length != 3) + continue; + // get the ID of the attachment + var links = item[2].querySelectorAll("a"); + if (links.length != 2) + continue; + var match = reAttachmentDiff.exec(links[1].href); + if (match) { + var attach_id = match[1]; + var parentNode = links[1].parentNode; + parentNode.appendChild(doc.createTextNode(" | ")); + var linkNode = doc.createElement("a"); + linkNode.href = reviewBoardUrlBase + "r/bzpatch/bug" + bug_id + "/attach" + attach_id + "/"; + linkNode.textContent = "Review"; + parentNode.appendChild(linkNode); + } + } +} + +function quicksearchHandler(doc) { + var win = doc.defaultView; + var match = /quicksearch=([^&]+)/i.exec(win.location.search); + if (match) { + var quicksearch = unescape(match[1].replace('+', ' ', 'g')); + var quicksearchBox = doc.querySelectorAll("input[name=quicksearch]"); + if (quicksearchBox) { + for (var i = 0; i < quicksearchBox.length; ++i) { + quicksearchBox[i].value = quicksearch; + } + } + } +} + +function AttachmentFlagHandlerCtor() { + this._db = {}; + this._interestingFlags = {}; +} +AttachmentFlagHandlerCtor.prototype = { + determineInterestingFlags: function (doc) { + var table = doc.getElementById("attachment_table"); + if (!table) + return; + var rows = table.querySelectorAll("tr"); + for (var i = 0; i < rows.length; ++i) { + var item = rows[i].querySelectorAll("td"); + if (item.length != 3 || + item[1].className.indexOf("bz_attach_flags") < 0 || + trimContent(item[1]) == "no flags") + continue; + // get the ID of the attachment + var link = item[0].querySelector("a"); + if (!link) + continue; + var match = this._reAttachmentHref.exec(link.href); + if (match) { + var attachmentID = match[1]; + if (!(attachmentID in this._interestingFlags)) { + this._interestingFlags[attachmentID] = []; + } + var text = ""; + var previousText = ""; + var previousEl = null; + for (var el = item[1].firstChild; el.nextSibling; el = el.nextSibling) { + var thisText = trimContent(el).replace('\u2011', '-', 'g'); + text += thisText; + if (this._reParsePartToLinkify.test(thisText)) { + previousText = thisText; + previousEl = el; + } + if (el.nodeType != el.ELEMENT_NODE || + el.localName.toLowerCase() != "br") + continue; + match = this._reParseInterestingFlag.exec(text); + if (match) { + var flag = {}; + flag.setter = match[1]; + flag.name = match[2]; + if (match[4] == "+" || match[4] == "-") { + flag.type = match[4]; + } else { + flag.type = "?"; + if (match[7]) { + flag.requestee = match[7]; + } + } + + // always show the obsolete attachments with a + flag + if (flag.type == "+") { + var parent = link.parentNode; + while (parent) { + if (parent.tagName.toLowerCase() == "tr") { + if (/bz_tr_obsolete/i.test(parent.className)) { + parent.className += " bztw_plusflag"; + } + break; + } + parent = parent.parentNode; + } + } + + // try to put the flag name and type part in a span + // which we will + // use in setupLinks to inject links into. + match = this._reLinkifyInterestingFlag.exec(previousText); + if (match) { + previousEl.textContent = match[1]; + if (match[3]) { + var textNode = doc.createTextNode(match[3]); + previousEl.parentNode.insertBefore(textNode, previousEl.nextSibling); + } + var span = doc.createElement("span"); + span.textContent = match[2]; + previousEl.parentNode.insertBefore(span, previousEl.nextSibling); + + flag.placeholder = span; + } + + this._interestingFlags[attachmentID].push(new AttachmentFlag(flag)); + } + text = ""; + previousText = ""; + previousEl = null; + } + } + } + }, + handleItem: function (name, item) { + var anchorsCreated = []; + var base = item[4] ? 2 : 0; + var what = trimContent(item[base]); + var match = this._reAttachmentFlagName.exec(what); + if (match) { + var id = match[1]; + if (!(id in this._db)) { + this._db[id] = []; + } + name = name.split('@')[0]; // convert the name to the fraction + // before the @ + var added = this._parseData(name, trimContent(item[base + 2])); + for (var i = 0; i < added.length; ++i) { + var flag = added[i]; + if (!(id in this._interestingFlags)) + continue; + for (var j = 0; j < this._interestingFlags[id].length; ++j) { + // Take care to not assign an anchor to a flag which already has one + if (flag.equals(this._interestingFlags[id][j]) && + !("anchor" in this._interestingFlags[id][j])) { + // found an interesting flag + this._interestingFlags[id][j].anchor = this.anchorName; + anchorsCreated.push(this.anchorName); + this._counter++; + break; + } + } + } + } + return anchorsCreated; + }, + setupLinks: function (doc) { + for (var id in this._interestingFlags) { + for (var i = 0; i < this._interestingFlags[id].length; ++i) { + var flag = this._interestingFlags[id][i]; + if ("placeholder" in flag && + "anchor" in flag) { + var link = doc.createElement("a"); + link.href = "#" + flag.anchor; + link.textContent = flag.placeholder.textContent; + flag.placeholder.replaceChild(link, flag.placeholder.firstChild); + } + } + } + }, + _parseData: function (name, str) { + var items = str.replace('\u2011', '-', 'g').split(', '), flags = []; + for (var i = 0; i < items.length; ++i) { + if (!items[i].length) + continue; + + var match = this._reParseRequest.exec(items[i]); + if (match) { + var flag = {}; + flag.name = match[1]; + flag.setter = name; + if (match[4]) { + flag.requestee = match[4]; + } + flag.type = match[2]; + flags.push(new AttachmentFlag(flag)); + } + } + return flags; + }, + _counter: 1, + get anchorName() { + return "attachflag" + this._counter; + }, + _reParseRequest: /^(.+)([\?\-\+])(\((.+)@.+\))?$/, + _reParsePartToLinkify: /^\s*:\s+.+[\-\+\?](\s*\()?\s*$/, + _reParseInterestingFlag: /^(.+):\s+(.+)(([\-\+])|\?(\s+(\((.+)\)))?)$/, + _reLinkifyInterestingFlag: /^(\s*:\s+)(.+[\-\+\?])(\s*\(\s*)?$/, + _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i, + _reAttachmentFlagName: /^Attachment\s+#(\d+)\s+Flags$/i +}; + +function CheckinCommentCtor() { + this.bugNumber = null; + this.summarySpan = null; + this.checkinFlags = ""; +} +CheckinCommentCtor.prototype = { + initialize: function(doc, flags) { + this.bugNumber = getBugNo(doc); + var summarySpan = doc.getElementById("short_desc_nonedit_display"); + if (summarySpan) { + this.summary = summarySpan.textContent; + } + var checkinFlagsMap = {}; + for (var id in flags) { + for (var i = 0; i < flags[id].length; ++i) { + var flag = flags[id][i]; + if (flag.type == "+") { + var name = flag.name; + if (name == "review") { + name = "r"; + } else if (name == "superreview") { + name = "sr"; + } else if (name == "ui-review") { + name = "ui-r"; + } else if (name == "feedback") { + name = "f"; + } + if (!(name in checkinFlagsMap)) { + checkinFlagsMap[name] = {}; + } + checkinFlagsMap[name][flag.setter]++; + } + } + } + var flagsOrdered = []; + for (var name in checkinFlagsMap) { + flagsOrdered.push(name); + } + flagsOrdered.sort(function (a, b) { + function convertToNumber(x) { + switch (x) { + case "f": + return -4; + case "r": + return -3; + case "sr": + return -2; + case "ui-r": + return -1; + default: + return 0; + } + } + var an = convertToNumber(a); + var bn = convertToNumber(b); + if (an == 0 && bn == 0) { + return a < b ? -1 : (a = b ? 0 : 1); + } else { + return an - bn; + } + }); + var checkinFlags = []; + for (var i = 0; i < flagsOrdered.length; ++i) { + var name = flagsOrdered[i]; + var flag = name + "="; + var setters = []; + for (var setter in checkinFlagsMap[name]) { + setters.push(setter); + } + flag += setters.join(","); + checkinFlags.push(flag); + } + this.checkinFlags = checkinFlags.join(" "); + if (this.isValid()) { + var div = doc.createElement("div"); + div.setAttribute("style", "display: none;"); + div.id = "__bz_tw_checkin_comment"; + div.appendChild(doc.createTextNode(this.toString())); + doc.body.appendChild(div); + } + }, + isValid: function() { + return this.bugNumber != null && + this.summary != null; + }, + toString: function() { + if (!this.isValid()) { + return ""; + } + var message = "Bug " + this.bugNumber + " - " + this.summary; + if (this.checkinFlags.length) { + message += "; " + this.checkinFlags; + } + return message; + } +}; + +function DataStoreCtor(doc) { + this.storage = doc.defaultView.localStorage; + this.data = {}; + this.bugNumber = null; + function visualizeStoredData() { + var data = ""; + for (var i = 0; i < window.localStorage.length; ++i) { + var key = window.localStorage.key(i); + data += key + ": " + JSON.parse(window.localStorage.getItem(key).toString()).toSource() + "\n"; + } + open("data:text/html,
    " + escape(htmlEncode(data)) + "
    "); + } + function clearStoredData() { + var count = window.localStorage.length; + if (count > 0) { + if (window.confirm("You currently have data stored for " + count + " bugs.\n\n" + + "Are you sure you want to clear this data? This action cannot be undone.")) { + window.localStorage.clear(); + } + } else { + alert("You don't have any data stored about your bugs"); + } + } + var script = doc.createElement("script"); + script.appendChild(doc.createTextNode(visualizeStoredData.toSource() + + clearStoredData.toSource() + + htmlEncode.toSource())); + doc.body.appendChild(script); + this.initialize(doc); +} + +DataStoreCtor.prototype = { + initialize: function(doc) { + this.bugNumber = getBugNo(doc); + var data = this._ensureEntry(this.bugNumber, this.data); + // last visited date + data.visitedTime = (new Date()).getTime(); + // last comment count + data.commentCount = doc.querySelectorAll(".bz_comment").length; + // last status of bug flags + var flags = this._ensureEntry("flags", data); + var flagRows = doc.querySelectorAll("#flags tr"); + for (var i = 0; i < flagRows.length; ++i) { + var flagCols = flagRows[i].querySelectorAll("td"); + if (flagCols.length != 3) { + continue; + } + var flagName = trimContent(flagCols[1]); + var flagValue = flagCols[2].querySelector("select"); + if (flagValue) { + flagValue = flagValue.value; + } else { + continue; + } + flags[flagName] = flagValue; + } + flagRows = doc.querySelectorAll(".field_label[id^=field_label_cf_]"); + for (var i = 0; i < flagRows.length; ++i) { + var flagName = trimContent(flagRows[i]).replace(/:$/, ""); + var flagValue = flagRows[i].parentNode.querySelector("select"); + if (flagValue) { + flagValue = flagValue.value; + } else { + continue; + } + flags[flagName] = flagValue; + } + // last attachments + var attachmentTable = doc.getElementById("attachment_table"); + var attachmentRows = attachmentTable.querySelectorAll("tr"); + for (var i = 0; i < attachmentRows.length; ++i) { + var attachmentCells = attachmentRows[i].querySelectorAll("td"); + if (attachmentCells.length != 3) { + continue; + } + var link = attachmentCells[0].querySelector("a"); + var match = this._reAttachmentHref.exec(link.href); + if (match) { + var attachmentID = match[1]; + var attachment = this._ensureEntry("attachments", data); + var attachmentFlags = this._ensureArray(attachmentID, attachment); + for (var el = attachmentCells[1].firstChild; el.nextSibling; el = el.nextSibling) { + if (el.nodeType != el.TEXT_NODE) { + continue; + } + var text = trimContent(el); + if (!text) { + continue; + } + match = this._reParseInterestingFlag.exec(text); + if (match) { + var flag = {}; + flag.setter = match[1]; + flag.name = match[2]; + if (match[4] == "+" || match[4] == "-") { + flag.type = match[4]; + } else { + flag.type = "?"; + if (match[7]) { + flag.requestee = match[7]; + } + } + attachmentFlags.push(flag); + } + } + } + } + // Write data to storage + for (var key in this.data) { + this._ensure(key, this.storage, JSON.stringify(this.data[key])); + } + }, + _ensure: function(entry, obj, val) { + if (obj.toString().indexOf("[object Storage") >= 0) { + obj.setItem(entry, val); + } else { + if (typeof obj[entry] == "undefined") + obj[entry] = val; + return obj[entry]; + } + }, + _ensureEntry: function(entry, obj) { + return this._ensure(entry, obj, {}); + }, + _ensureArray: function(entry, obj) { + return this._ensure(entry, obj, []); + }, + _reParseInterestingFlag: /^(.+):\s+(.+)(([\-\+])|\?(\s+(\((.+)\)))?)$/, + _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i +}; + + +function getUserName(doc) { + var links = doc.querySelectorAll("#header .links li"); + var last = links[links.length - 1]; + if (last.innerHTML.indexOf("logout") >= 0) { + return trimContent(last.lastChild); + } + return null; +} + +function handleEmptyCollapsedBoxes(doc) { + // first, try to get the display style of a CC field (any would do) + var historyBoxes = doc.querySelectorAll(".bztw_history"); + for (var i = 0; i < historyBoxes.length; ++i) { + var box = historyBoxes[i]; + for (var j = 0; j < box.childNodes.length; ++j) { + var child = box.childNodes[j], found = true; + if (child.nodeType != child.ELEMENT_NODE) + continue; + if (child.className == "sep") { + // separators are insignificant + continue; + } else if (!/bztw_cc/.test(child.className)) { + found = false; + break; + } + } + if (found) { + box.className += " bztw_cc"; + } + } +} + +function applyClass(class_, html) { + return '' + html + ''; +} + +function htmlEncode(str) { + return str.replace('&', '&', 'g') + .replace('<', '<', 'g') + .replace('>', '>', 'g') + .replace('"', '"', 'g'); +} + +function tbplbotSpamCollapser(d) { + var collapseExpandBox = d.querySelector(".bz_collapse_expand_comments"); + if (!collapseExpandBox) { + return; + } + var a = d.createElement("a"); + a.href = "#"; + a.addEventListener("click", function(e) { + e.preventDefault(); + var win = d.defaultView; + var comments = d.querySelectorAll(".bz_comment"); + for (var i = 0; i < comments.length; ++i) { + var comment = comments[i]; + try { + if (comment.querySelector(".bz_comment_user a.email").href.substr(7) == + "tbplbot@gmail.com") { + win.collapse_comment(comment.querySelector(".bz_collapse_comment"), + comment.querySelector(".bz_comment_text")); + } + } catch (e) { + continue; + } + } + return false; + }, false); + a.appendChild(d.createTextNode("Collapse All tbplbot Comments")); + var li = d.createElement("li"); + li.appendChild(a); + collapseExpandBox.appendChild(li); +} + +tweakBugzilla(document); diff --git a/data/tweaks/cc-context.js b/data/tweaks/cc-context.js new file mode 100644 index 0000000..81b0a2d --- /dev/null +++ b/data/tweaks/cc-context.js @@ -0,0 +1,8 @@ +self.on('click', function(node, data) { + var style = document.getElementById("bztw_cc"); + style.disabled = !style.disabled; +}); + +self.on('context', function(node) { + return onBugzillaPage(document.URL); +}); diff --git a/data/tweaks/checkin-context.js b/data/tweaks/checkin-context.js new file mode 100644 index 0000000..0ccec0c --- /dev/null +++ b/data/tweaks/checkin-context.js @@ -0,0 +1,13 @@ +self.on('click', function(node, data) { + var message = document + .getElementById("__bz_tw_checkin_comment"); + self.postMessage(message.textContent); +}); + +self.on('context', function(node) { + if (!onBugzillaPage(document.URL)) + return false; + var message = document + .getElementById("__bz_tw_checkin_comment"); + return !!message; +}); diff --git a/data/tweaks/preprocessDuplicates.js b/data/tweaks/preprocessDuplicates.js new file mode 100644 index 0000000..d312fb9 --- /dev/null +++ b/data/tweaks/preprocessDuplicates.js @@ -0,0 +1,132 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Bugzilla Tweaks. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johnathan Nightingale + * Ehsan Akhgari + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +function preprocessDuplicateMarkers(mainDoc, histDoc) { + var comments = mainDoc.querySelectorAll(".bz_comment"); + var reDuplicate = /^\s*\*\*\*\s+Bug\s+(\d+)\s+has\s+been\s+marked\s+as\s+a\s+duplicate\s+of\s+this\s+bug.\s+\*\*\*\s*$/i; + var row = 0; + var rows = histDoc.querySelectorAll("#bugzilla-body tr"); + for ( var i = 1 /* comment 0 can never be a duplicate marker */; i < comments.length; ++i) { + var textHolder = comments[i] + .querySelector(".bz_comment_text"); + var match = reDuplicate.exec(trimContent(textHolder)); + if (match) { + // construct the table row to be injected in histDoc + var bugID = match[1]; + var email = comments[i] + .querySelector(".bz_comment_user .email").href + .substr(7); + var link = textHolder.querySelector("a"); + var title = link.title; + var time = trimContent(comments[i] + .querySelector(".bz_comment_time")); + var what = 'Duplicate'; + var removed = ''; + var number = trimContent( + comments[i].querySelector(".bz_comment_number")) + .replace(/[^\d]+/g, ''); + var class_ = ''; + if (/bz_closed/i.test(link.className + " " + + link.parentNode.className)) { + class_ += 'bz_closed '; + } + if (link.parentNode.tagName.toLowerCase() == 'i') { + class_ += 'bztw_unconfirmed '; + } + var added = '' + bugID + + ''; + + // inject the table row + var reachedEnd = false; + for (; row < rows.length; ++row) { + var cells = rows[row].querySelectorAll("td"); + if (cells.length != 5) + continue; + if (time > trimContent(cells[1])) { + if (row < rows.length - 1) { + continue; + } + else { + reachedEnd = true; + } + } + if (time == trimContent(cells[1])) { + cells[0].rowSpan++; + cells[1].rowSpan++; + var rowContents = [ + what, removed, added + ]; + var tr = histDoc.createElement("tr"); + rowContents.forEach(function(cellContents) { + var td = histDoc.createElement("td"); + td.innerHTML = cellContents; + tr.appendChild(td); + }); + if (row != rows.length - 1) { + rows[row].parentNode.insertBefore(tr, rows[row + 1]); + } + else { + rows[row].parentNode.appendChild(tr); + } + } + else { + var rowContents = [ + email, time, what, removed, added + ]; + var tr = histDoc.createElement("tr"); + rowContents.forEach(function(cellContents) { + var td = histDoc.createElement("td"); + td.innerHTML = cellContents; + tr.appendChild(td); + }); + if (reachedEnd) { + rows[row].parentNode.appendChild(tr); + } + else { + rows[row].parentNode.insertBefore(tr, rows[row]); + } + } + break; + } + + // remove the comment from the main doc + comments[i].parentNode.removeChild(comments[i]); + } + } +} diff --git a/data/tweaks/urltest.js b/data/tweaks/urltest.js new file mode 100644 index 0000000..609e77b --- /dev/null +++ b/data/tweaks/urltest.js @@ -0,0 +1,5 @@ +function onBugzillaPage(url) { + return /https:\/\/bugzilla(-[a-zA-Z]+)*\.mozilla\.org/ + .test(url) + || /https:\/\/landfill.*\.bugzilla\.org/.test(url); +} diff --git a/data/tweaks/viewSource.js b/data/tweaks/viewSource.js new file mode 100644 index 0000000..fd47cec --- /dev/null +++ b/data/tweaks/viewSource.js @@ -0,0 +1,104 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Bugzilla Tweaks. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Johnathan Nightingale + * Ehsan Akhgari + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var reAttachmentType = /,\s+([^ )]*)[;)]/; + +function viewAttachmentSource(doc) { + function addLink(elem, title, href) { + if (elem.textContent.match(/[\S]/)) { + elem.appendChild(doc.createTextNode(" | ")); + } + var link = doc.createElement("a"); + link.href = href; + link.textContent = title; + elem.appendChild(link); + } + var table = doc.getElementById("attachment_table"); + if (!table) + return; + var rows = table.querySelectorAll("tr"); + for ( var i = 0; i < rows.length; ++i) { + var items = rows[i].querySelectorAll("td"); + if (items.length != 3) + continue; + var links = items[0].querySelectorAll("a"); + if (links.length == 0) + continue; + var attachHref = links[0].href; + // get the type of the attachment + var span = items[0].querySelector(".bz_attach_extra_info"); + if (!span) + continue; + var typeName = null; + try { + // Match mime type followed by ";" (charset) or ")" (no charset) + typeName = span.textContent.match(reAttachmentType)[1]; + typeName = typeName.split(";")[0]; // ignore charset following type + } + catch (e) { + } + if (typeName == "application/java-archive" + || typeName == "application/x-jar") { + // Due to the fix for bug 369814, only zip files with this special + // mime type can be used with the jar: protocol. + // http://hg.mozilla.org/mozilla-central/rev/be54f6bb9e1e + addLink(items[2], "JAR Contents", "jar:" + attachHref + + "!/"); + // https://bugzilla.mozilla.org/show_bug.cgi?id=369814#c5 has more + // possible mime types for zips? + } + else if (typeName == "application/zip" + || typeName == "application/x-zip-compressed" + || typeName == "application/x-xpinstall") { + addLink(items[2], "Static ZIP Contents", "jar:" + + attachHref + "!/"); + } + else if (typeName != "text/plain" && typeName != "patch" && + // Other types that Gecko displays like text/plain + // http://mxr.mozilla.org/mozilla-central/source/parser/htmlparser/public/nsIParser.h + typeName != "text/css" && typeName != "text/javascript" + && typeName != "text/ecmascript" + && typeName != "application/javascript" + && typeName != "application/ecmascript" + && typeName != "application/x-javascript" && + // Binary image types for which the "source" is not useful + typeName != "image/gif" && typeName != "image/png" + && typeName != "image/jpeg") { + addLink(items[2], "Source", "view-source:" + attachHref); + } + } +} diff --git a/docs/bzpage.md b/docs/bzpage.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/rhbzpage.md b/docs/rhbzpage.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/xhr.md b/docs/xhr.md deleted file mode 100644 index ea21c80..0000000 --- a/docs/xhr.md +++ /dev/null @@ -1,82 +0,0 @@ -The `xhr` module provides access to `XMLHttpRequest` -functionality, also known as AJAX. - -## Exports ## - -xhr.**XMLHttpRequest**() - -Creates an `XMLHttpRequest`. This is a constructor, so its use -should always be preceded by the `new` operator. For more information, -see the MDC page on [Using XMLHttpRequest]. - -xhr.**getRequestCount**() - -Returns the number of `XMLHttpRequest` objects that are alive -(i.e., currently active or about to be). - -## Limitations ## - -The `XMLHttpRequest` object is currently fairly limited, and does not -yet implement the `addEventListener()` or `removeEventListener()` -methods. It also doesn't yet implement the `upload` property. - -Furthermore, the `XMLHttpRequest` object does not currently support -the `mozBackgroundRequest` property. All security UI, such as -username/password prompts, are automatically suppressed, so if -required authentication information isn't passed to the `open()` -method, the request will fail. - -## Resource Use ## - -Whenever this module is unloaded, all in-progress requests are immediately -aborted. - -## Security Concerns ## - -By default, the `XMLHttpRequest` object grants full access to any -protocol scheme, which means that it can be used to read from (but not -write to) the host system's entire filesystem. It also has unfettered -access to any local area networks, VPNs, and the internet. - -### Threat Model ### - -The `XMLHttpRequest` object can be used by an extension to "phone -home" and transmit potentially sensitive user data to third -parties. - -If access to the filesystem isn't prevented, it could easily be used -to access sensitive user data, though this may be inconsequential if -the client can't access the network. - -If access to local area networks isn't prevented, malicious Jetpack -code could access sensitive data. - -If transmission of cookies isn't prevented, malicious Jetpack code -could access sensitive data. - -Attenuating access based on a regular expression may be ineffective if -it's easy to write a regular expression that *looks* safe but contains -a special character or two that makes it far less secure than it seems -at first glance. - -### Possible Attenuations ### - - -We may also want to consider attenuating further based on domain name -and possibly even restricting the protocol to `https:` only, to reduce -risk. - - -Before being exposed to unprivileged Jetpack code, this object needs -to be attenuated in such a way that, at the very least, it can't -access the user's filesystem. This can probably be done most securely -by white-listing the protocols that can be used in the URL passed to -the `open()` method, and limiting them to `http:`, `https:`, and -possibly a special scheme that can be used to access the Jetpack -extension's packaged, read-only resources. - -Finally, we need to also consider attenuating http/https requests such -that they're "sandboxed" and don't communicate potentially sensitive -cookie information. - - [Using XMLHttpRequest]: https://developer.mozilla.org/En/Using_XMLHttpRequest diff --git a/lib/main.js b/lib/main.js index f3e9458..c7fe2fd 100644 --- a/lib/main.js +++ b/lib/main.js @@ -29,7 +29,7 @@ function isOurPage(window, matchingURLs) { } /** - * + * */ function skipThisPage(doc) { var stemURL = "https://HOSTNAME/show_bug.cgi?id="; @@ -119,22 +119,22 @@ var messageHandler = exports.messageHandler = function messageHandler( }; var contentScriptLibraries = [ - self.data.url('lib/urltest.js'), + self.data.url('tweaks/urltest.js'), self.data.url("lib/util.js"), self.data.url("lib/jumpNextBug.js"), self.data.url("lib/queries.js"), self.data.url("lib/preprocessDuplicates.js"), - self.data.url("lib/viewSource.js"), + self.data.url("tweaks/viewSource.js"), self.data.url("lib/color.js"), - self.data.url("lib/addNewLinks.js"), + self.data.url("tweaks/addNewLinks.js"), self.data.url("lib/bugzillaDOMFunctions.js"), - self.data.url("lib/xorgBugCategories.js"), + self.data.url("rhlib/xorgBugCategories.js"), self.data.url("lib/otherButtons.js"), self.data.url("lib/makeBacktraceAttachment.js"), - self.data.url("lib/fixingAttMIME.js"), + self.data.url("rhlib/fixingAttMIME.js"), self.data.url("lib/logging-front.js"), - self.data.url('lib/bug-page-mod.js'), - self.data.url("lib/rhbzpage.js"), + self.data.url('tweaks/bug-page-mod.js'), + self.data.url("rhlib/rhbzpage.js"), self.data.url("lib/bzpage.js") ]; @@ -175,16 +175,16 @@ pageMod.PageMod({ contextMenu.Item({ label : "Toggle CC History", contentScriptFile : [ - self.data.url('lib/urltest.js'), - self.data.url('lib/cc-context.js') + self.data.url('tweaks/urltest.js'), + self.data.url('tweaks/cc-context.js') ] }); contextMenu.Item({ label : "Copy Check-in Comment", contentScriptFile : [ - self.data.url('lib/urltest.js'), - self.data.url('lib/checkin-context.js') + self.data.url('tweaks/urltest.js'), + self.data.url('tweaks/checkin-context.js') ], onMessage : function(comment) { require("clipboard").set(comment); -- cgit From 272ab432ddc4562237c7235f8e0ab8a11bad3d3d Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 29 Apr 2011 01:22:18 +0200 Subject: All XML-RPC calls are rewritten as JSON-RPC ones. * also MakeJSONRPCall is a functional call now * reorganization for dealing with the history. --- data/XMLRPCdata.json | 9 +- data/lib/addAttachmentRow.js | 32 +- data/lib/bzpage.js | 23 +- data/lib/util.js | 8 +- data/rhlib/fixingAttMIME.js | 11 +- data/tweaks/bug-page-mod.js | 1586 +++++++++++++++++++++++------------------- lib/libbugzilla.js | 87 ++- lib/main.js | 11 +- 8 files changed, 985 insertions(+), 782 deletions(-) diff --git a/data/XMLRPCdata.json b/data/XMLRPCdata.json index 4dab662..e378f22 100644 --- a/data/XMLRPCdata.json +++ b/data/XMLRPCdata.json @@ -1,8 +1,11 @@ { "bugzilla.redhat.com": { - "url": "https://bugzilla.redhat.com/xmlrpc.cgi" + "url": "https://bugzilla.redhat.com/xmlrpc.cgi" + }, + "bugzilla.mozilla.org": { + "url": "https://bugzilla.mozilla.org/xmlrpc.cgi" }, "bz-web2-test.devel.redhat.com": { - "url": "https://bz-web2-test.devel.redhat.com/xmlrpc.cgi" + "url": "https://bz-web2-test.devel.redhat.com/xmlrpc.cgi" } -} \ No newline at end of file +} diff --git a/data/lib/addAttachmentRow.js b/data/lib/addAttachmentRow.js index a2b67ee..3bee73a 100644 --- a/data/lib/addAttachmentRow.js +++ b/data/lib/addAttachmentRow.js @@ -2,6 +2,7 @@ // http://www.opensource.org/licenses/mit-license.php "use strict"; +// FIXME resp is JSON, not XML anymore function addAttachmentCallback(resp) { var newAttachID = parseInt( resp.params.param.value.array.data.value.int, 10); @@ -13,6 +14,25 @@ function addAttachmentCallback(resp) { * * This has to stay in RHBugzillaPage because upstream doesn't have * addAttachment XML-RPC call yet. + * + Params: $params = { + id => '', # ID of the bug report + comment => "", # OPTIONAL Text string containing comment to add. + description => "", # REQUIRED Text Description of the attachment. + isprivate => , # OPTIONAL Whether the Attachment + will be private # Default: false + filename => "", REQUIRED The name of the file to attach to the bug report. + obsoletes => [List of attach_id's to obsolete], OPTIONAL List if attachment ids that are + obsoleted by this new attachment. + ispatch => , OPTIONAL Whether the attachment is a Patch + or not, if not provided the it will be considered NON Patch attachment. + contenttype => "", OPTIONAL If the attachment is patch + REQUIRED If the attachment is not a patch + If the attachment is patch then contenttype will always be text/plain + data => "", REQUIRED It is a base64 + encoded string of the actual attachment data. + nomail => 0, OPTIONAL Flag that is either 1 or 0 if you want email + to be send ot not for this change } */ function addAttachment(data, callback, param) { var params = []; @@ -23,18 +43,18 @@ function addAttachment(data, callback, param) { return null; } - params.push(getBugNo()); - params.push({ + var params = { + id: getBugNo(), description : titleParsedAttachment, filename : "parsed-backtrace.txt", contenttype : "text/plain", data : window.btoa(data), nomail : true - }); + }; - self.postMessage(new Message("MakeXMLRPCall", { - url : constantData.XMLRPCData[window.location.hostname].url, - login : getLogin(), + self.postMessage(new Message("MakeJSONRPCCall", { + url : constantData.XMLRPCData[window.location.hostname].url. + replace("xmlrpc.cgi","jsonrpc.cgi"), method : "bugzilla.addAttachment", params : params, callRPC : "AddAttachmentCallback" diff --git a/data/lib/bzpage.js b/data/lib/bzpage.js index 9e65794..02c8e3c 100644 --- a/data/lib/bzpage.js +++ b/data/lib/bzpage.js @@ -43,8 +43,8 @@ onMessage = function onMessage(msg) { case "Unhandled": break; default: - if (RHOnMessageHandler) { - RHOnMessageHandler(msg); + if (TweakOnMessageHandler) { + TweakOnMessageHandler(msg, RHOnMessageHandler); } else { console.error("Error: unknown RPC call " + msg.toSource()); @@ -55,7 +55,7 @@ onMessage = function onMessage(msg) { /** * @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 @@ -73,7 +73,7 @@ function executeCommand(cmdObj) { /** * Actual execution function - * + * * @param cmdLabel * String with the name of the command to be executed * @param cmdParams @@ -184,7 +184,7 @@ function centralCommandDispatch (cmdLabel, cmdParams) { /** * Change assignee of the bug - * + * * @param newAssignee * String with the email address of new assigneeAElement or 'default' * if the component's default assignee should be used. Value null @@ -228,7 +228,7 @@ function changeAssignee (newAssignee) { /** * Adds new option to the 'comment_action' scroll down box - * + * * @param pkg * String package name * @param cmd @@ -312,8 +312,13 @@ function generateButtons (pkgs, kNodes) { // constantData etc. // are finally defined and available. if (RHBZinit) { + console.log("call RHBZinit!"); RHBZinit(); } + + if (tweakBugzilla) { + tweakBugzilla(document, constantData); + } } function setConfigurationButton () { @@ -333,7 +338,7 @@ function setConfigurationButton () { /** * dd - * + * * @return Element with the href attribute containng the information */ function getOptionTableCell(tableId, label) { @@ -356,13 +361,13 @@ function getOptionTableCell(tableId, label) { /** * Parse the row with the attachment - * + * * @param DOM * 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 - * + * * TODO error handling is missing ... it's bleee */ function parseAttachmentLine(inElem) { diff --git a/data/lib/util.js b/data/lib/util.js index be674bc..064887c 100644 --- a/data/lib/util.js +++ b/data/lib/util.js @@ -68,12 +68,8 @@ function parseXMLfromString (inStuff) { * Get a bug no */ function getBugNo() { - var bugNoElem = document.forms.namedItem('changeform').getElementsByName("id")[0]; - if (bugNoElem) { - return bugNoElem.value; - } else { - return null; - } + console.log("bugNo = " + document.getElementsByName("id")[0].value); + return document.getElementsByName("id")[0].value; } /** diff --git a/data/rhlib/fixingAttMIME.js b/data/rhlib/fixingAttMIME.js index 365cfae..c2adde4 100644 --- a/data/rhlib/fixingAttMIME.js +++ b/data/rhlib/fixingAttMIME.js @@ -45,8 +45,6 @@ function XMLRPCcallback() { * */ function fixAttachById(id, XMLRPCURL, type, email) { - var params = []; - if (type === undefined) { type = "text/plain"; } @@ -57,15 +55,14 @@ function fixAttachById(id, XMLRPCURL, type, email) { // 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({ + var params = { 'attach_id' : id, 'mime_type' : type, 'nomail' : !email - }); + }; - self.postMessage(new Message("MakeXMLRPCall", { - url : XMLRPCURL, - login : getLogin(), + self.postMessage(new Message("MakeJSONRPCall", { + url : XMLRPCURL.replace("xmlrpc.cgi","jsonrpc.cgi"), method : "bugzilla.updateAttachMimeType", params : params, callRPC : "FixAttachmentMIMECallback" diff --git a/data/tweaks/bug-page-mod.js b/data/tweaks/bug-page-mod.js index a7fb7e7..c2b529e 100644 --- a/data/tweaks/bug-page-mod.js +++ b/data/tweaks/bug-page-mod.js @@ -1,487 +1,647 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +/******************************************************************************* + * ***** BEGIN LICENSE BLOCK Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ + * 1.1 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. * * The Original Code is Bugzilla Tweaks. * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. + * The Initial Developer of the Original Code is Mozilla Foundation. Portions + * created by the Initial Developer are Copyright (C) 2010 the Initial + * Developer. All Rights Reserved. * - * Contributor(s): - * Johnathan Nightingale - * Ehsan Akhgari + * Contributor(s): Johnathan Nightingale Ehsan Akhgari + * * * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * either the GNU General Public License Version 2 or later (the "GPL"), or the + * GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which + * case the provisions of the GPL or the LGPL are applicable instead of those + * above. If you wish to allow use of your version of this file only under the + * terms of either the GPL or the LGPL, and not to allow others to use your + * version of this file under the terms of the MPL, indicate your decision by + * deleting the provisions above and replace them with the notice and other + * provisions required by the GPL or the LGPL. If you do not delete the + * provisions above, a recipient may use your version of this file under the + * terms of any one of the MPL, the GPL or the LGPL. * - * ***** END LICENSE BLOCK ***** */ + * ***** END LICENSE BLOCK ***** + */ + +function TweakOnMessageHandler(msg, nextHandler) { + switch (msg.cmd) { + case "Unhandled": + break; + case "returnedHistory": + processHistory(msg.data); + break; + default: + if (nextHandler) { + nextHandler(msg); + } + else { + console.error("Error: unknown RPC call " + msg.toSource()); + } + break; + } +} -function tweakBugzilla(d) { - // run on both bugzilla.m.o and bugzilla-stage-tip.m.o - // if (!onBugzillaPage(d.URL)) - // return; +/** + * generate XML-RPC call to collect complete history of the bug + * @param XMLRPCURL URL of the XML-RPC gateway on the particular bugzilla + * @returns nothing + * + * As part of the message is name of the signal "returnedHistory" + */ +function collectHistory(rpcURL) { + // https://bugzilla.redhat.com/docs/en/html/api/Bugzilla\ + // /WebService/Bug.html#Bug_Information + var bugId = getBugNo(); + self.postMessage(new Message("MakeJSONRPCall", { + url : rpcURL.replace("xmlrpc.cgi","jsonrpc.cgi"), + login : getLogin(), + method : "Bug.history", + params : { "ids": [ bugId ] }, + callRPC : "returnedHistory" + })); +} - // Put the quicksearch text in the quicksearch boxes - quicksearchHandler(d); +function tweakBugzilla(d, cData) { + // run on both bugzilla.m.o and bugzilla-stage-tip.m.o + // if (!onBugzillaPage(d.URL)) + // return; - if (!d.getElementById("comments")) // don't process the mid-air collision - // pages - return; + // Put the quicksearch text in the quicksearch boxes + quicksearchHandler(d); - // Make the comment box bigger ... TODO not necessary on RH BZ, but doesn't hurt - var commentBox = d.getElementById("comment"); - if (commentBox) - commentBox.rows=20; + if (!d.getElementById("comments")) // don't process the mid-air collision + // pages + return; - addNewLinks(d); + // Make the comment box bigger + var commentBox = d.querySelector("#comment"); + if (commentBox) + commentBox.rows=20; - attachmentDiffLinkify(d); + addNewLinks(d); - viewAttachmentSource(d); + attachmentDiffLinkify(d); - // Mark up history along right hand edge - // TODO ... not sure what does this mean ... this - // element is I suppose everywhere. - var historyLink = d.querySelector("link[title='Bug Activity']"); - if (!historyLink) - return; + viewAttachmentSource(d); - // Add our own style for bugzilla-tweaks - var style = d.createElement("style"); - style.setAttribute("type", "text/css"); - style.appendChild(d.createTextNode( - ".bztw_history { border: none; font-weight: normal; width: 58em; margin-left: 5em; }" + - ".bztw_inlinehistory { font-weight: normal; width: 56em; }" + - ".bztw_history .old, .bztw_inlinehistory .old { text-decoration: line-through; }" + - ".bztw_history .sep:before { content: \" \"; }" + - ".bztw_unconfirmed { font-style: italic; }" + - "tr.bz_tr_obsolete.bztw_plusflag { display: table-row !important; }" + - '.bztw_historyitem + .bztw_historyitem:before { content: "; "; }' - )); - d.getElementsByTagName("head")[0].appendChild(style); - style = d.createElement("style"); - style.setAttribute("type", "text/css"); - style.id = "bztw_cc"; - style.appendChild(d.createTextNode( - ".bztw_cc { display: none; }" + - '.bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: ""; }' + - '.bztw_historyitem:not([class~="bztw_cc"]) ~ .bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: "; "; }' - )); - d.getElementsByTagName("head")[0].appendChild(style); - - var userNameCache = {}; - function getUserName(email) { - if (email in userNameCache) { - return userNameCache[email]; - } - var emailLink = d.querySelectorAll("a.email"); - for (var i = 0; i < emailLink.length; ++i) { - if (emailLink[i].href == "mailto:" + email) { - return userNameCache[email] = htmlEncode(trimContent(emailLink[i])); - } - } - return email; + // Mark up history along right hand edge + var historyLink = d.querySelector("link[title='Bug Activity']"); + if (!historyLink) + return; + + // Add our own style for bugzilla-tweaks + var style = d.createElement("style"); + style.setAttribute("type", "text/css"); + style.appendChild(d.createTextNode( + ".bztw_history { border: none; font-weight: normal; width: 58em; margin-left: 5em; }" + + ".bztw_inlinehistory { font-weight: normal; width: 56em; }" + + ".bztw_history .old, .bztw_inlinehistory .old { text-decoration: line-through; }" + + ".bztw_history .sep:before { content: \" \"; }" + + ".bztw_unconfirmed { font-style: italic; }" + + "tr.bz_tr_obsolete.bztw_plusflag { display: table-row !important; }" + + '.bztw_historyitem + .bztw_historyitem:before { content: "; "; }' + )); + d.getElementsByTagName("head")[0].appendChild(style); + style = d.createElement("style"); + style.setAttribute("type", "text/css"); + style.id = "bztw_cc"; + style.appendChild(d.createTextNode( + ".bztw_cc { display: none; }" + + '.bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: ""; }' + + '.bztw_historyitem:not([class~="bztw_cc"]) ~ .bztw_historyitem.bztw_cc + .bztw_historyitem:before { content: "; "; }' + )); + d.getElementsByTagName("head")[0].appendChild(style); + + // UserNameCache + var userNameCache = {}; + function getUserName(email) { + if (email in userNameCache) { + return userNameCache[email]; + } + var emailLink = d.querySelectorAll("a.email"); + for (var i = 0; i < emailLink.length; ++i) { + if (emailLink[i].href == "mailto:" + email) { + return userNameCache[email] = htmlEncode(trimContent(emailLink[i])); + } } + return email; + } - // collect the flag names - var flagNames = [], flags = {}, flagOccurrences = {}; - var flagRows = d.querySelectorAll("#flags tr"); - for (var i = 0; i < flagRows.length; ++i) { - var item = flagRows[i].querySelectorAll("td"); - if (!item[1]) - continue; - var name = trimContent(item[1]).replace('\u2011', '-', 'g'); - flagNames.push(name); - flags[name] = item[1]; + // collect the flag names + var flagNames = [], flags = {}, flagOccurrences = {}; + var flagRows = d.querySelectorAll("#flags tr"); + for (var i = 0; i < flagRows.length; ++i) { + var item = flagRows[i].querySelectorAll("td"); + if (!item[1]) + continue; + var name = trimContent(item[1]).replace('\u2011', '-', 'g'); + flagNames.push(name); + flags[name] = item[1]; + } + flagRows = d.querySelectorAll(".field_label[id^=field_label_cf_]"); + for (var i = 0; i < flagRows.length; ++i) { + var name = trimContent(flagRows[i]).replace(/\:$/, '') + .replace('\u2011', '-', 'g'); + flagNames.push(name); + flags[name] = flagRows[i]; + } + var flagCounter = 1; + + // ================================================= + function findFlag(item) { + function lookup(name) { + name = name.replace('\u2011', '-', 'g'); + for (var i = 0; i < flagNames.length; ++i) { + var quotedFlagName = flagNames[i].replace('.', '\\.', 'g') + .replace('\u2011', '-', 'g'); + if ((new RegExp('^' + quotedFlagName)).test(name)) { + return [flagNames[i]]; + } + } + return []; } - flagRows = d.querySelectorAll(".field_label[id^=field_label_cf_]"); - for (var i = 0; i < flagRows.length; ++i) { - var name = trimContent(flagRows[i]).replace(/\:$/, '') - .replace('\u2011', '-', 'g'); - flagNames.push(name); - flags[name] = flagRows[i]; + var base = item[4] ? 2 : 0; + // handle normal flags + if (trimContent(item[base]) == 'Flag') { + var result = []; + var tmp = lookup(trimContent(item[base + 1])); + if (tmp.length) { + result.push(tmp[0]); + } + tmp = lookup(trimContent(item[base + 2])); + if (tmp.length) { + result.push(tmp[0]); + } + return result; } - var flagCounter = 1; - - // ================================================= - function findFlag(item) { - function lookup(names) { - names = names.split(", "); - var results = []; - for (var j = 0; j < names.length; ++j) { - var name = names[j].replace('\u2011', '-', 'g'); - for (var i = 0; i < flagNames.length; ++i) { - var quotedFlagName = flagNames[i].replace('.', '\\.', 'g') - .replace('\u2011', '-', 'g'); - if ((new RegExp('^' + quotedFlagName)).test(name)) { - results.push(flagNames[i]); - break; + // handle special pseudo-flags + return lookup(trimContent(item[base])); + } + + var DataStore = new DataStoreCtor(d); + + var AttachmentFlagHandler = new AttachmentFlagHandlerCtor(); + AttachmentFlagHandler.determineInterestingFlags(d); + + var CheckinComment = new CheckinCommentCtor(); + CheckinComment.initialize(d, AttachmentFlagHandler._interestingFlags); + + var XMLRPCUrl = cData.XMLRPCData[d.location.hostname].url; + collectHistory(XMLRPCUrl); + + tbplbotSpamCollapser(d); +} + +// =================================================== +function processHistory(history) { + // FIXME Remove remaining code to special function ... callback +// preprocessDuplicateMarkers(d, iframe.contentDocument); + +/* +This is an example of the history we get: +{ + "version": "1.1", + "result": { + "bugs": [ + { + "history": [ + { + "when": "2011-04-04T00:19:04Z", + "who": "cebbert@redhat.com", + "changes": [ + { + "removed": "", + "added": "xgl-maint@redhat.com", + "field_name": "cc", + "field": "CC" + }, + { + "removed": "kernel", + "added": "xorg-x11-drv-ati", + "field_name": "component", + "field": "Component" + }, + { + "removed": "kernel-maint@redhat.com", + "added": "xgl-maint@redhat.com", + "field_name": "assigned_to", + "field": "AssignedTo" + } + ] + }, + { + "when": "2011-04-12T22:48:22Z", + "who": "mcepl@redhat.com", + "changes": [ + { + "attachment_id": 488889, + "removed": "application/octet-stream", + "added": "text/plain", + "field_name": "attachments.mimetype", + "field": "Attachment mime type" + } + ] + }, + { + "when": "2011-04-13T17:07:04Z", + "who": "mcepl@redhat.com", + "changes": [ + { + "removed": "", + "added": "needinfo?(suckfish@ihug.co.nz)", + "field_name": "flagtypes.name", + "field": "Flags" + } + ] + }, + { + "when": "2011-04-21T12:17:33Z", + "who": "mcepl@redhat.com", + "changes": [ + { + "removed": "xgl-maint@redhat.com", + "added": "jglisse@redhat.com", + "field_name": "assigned_to", + "field": "AssignedTo" + } + ] + }, + { + "when": "2011-04-28T22:53:58Z", + "who": "mcepl@redhat.com", + "changes": [ + { + "attachment_id": 488889, + "removed": "text/plain", + "added": "application/octet-stream", + "field_name": "attachments.mimetype", + "field": "Attachment mime type" + } + ] + }, + { + "when": "2011-04-28T22:59:18Z", + "who": "mcepl@redhat.com", + "changes": [ + { + "attachment_id": 488889, + "removed": "application/octet-stream", + "added": "text/plain", + "field_name": "attachments.mimetype", + "field": "Attachment mime type" + } + ] } - } + ], + "id": 692250, + "alias": [ + + ] } - return results; - } - var base = item[4] ? 2 : 0; - // handle normal flags - if (trimContent(item[base]) == 'Flags') { - var result = lookup(trimContent(item[base + 1])). - concat(lookup(trimContent(item[base + 2]))); - return result; - } - // handle special pseudo-flags - return lookup(trimContent(item[base])); + ], + "faults": [ + + ] } +} + */ - var DataStore = new DataStoreCtor(d); - - var AttachmentFlagHandler = new AttachmentFlagHandlerCtor(); - AttachmentFlagHandler.determineInterestingFlags(d); - - var CheckinComment = new CheckinCommentCtor(); - CheckinComment.initialize(d, AttachmentFlagHandler._interestingFlags); - - var iframe = d.createElement('iframe'); - iframe.src = historyLink.href; - iframe.style.display = "none"; - iframe.addEventListener("load", function() { - preprocessDuplicateMarkers(d, iframe.contentDocument); - - var historyItems = iframe.contentDocument.querySelectorAll('#bugzilla-body tr'); - var commentTimes = d.querySelectorAll('.bz_comment_time'); - - // Sometimes the history will stack several changes together, - // and we'll want to append the data from the Nth item to the - // div created in N-1 - var i=0, j=0, flagsFound; - for (; i < historyItems.length; i++) { - var item = historyItems[i].querySelectorAll("td"); - if (!item[1]) - continue; - - var reachedEnd = false; - for (; j < commentTimes.length; j++) { - if (trimContent(item[1]) > trimContent(commentTimes[j])) { - if (j < commentTimes.length - 1) { - continue; - } else { - reachedEnd = true; - } - } + if (history) { +// console.log("processHistory: history = " + history.toSource()); + return ; + } - var commentHead = commentTimes[j].parentNode; - - var mainUser = commentHead.querySelector(".bz_comment_user a.email") - .href - .substr(7); - var user = trimContent(item[0]); - var mainTime = trimContent(commentTimes[j]); - var time = trimContent(item[1]); - var inline = (mainUser == user && time == mainTime); - - var currentDiv = d.createElement("div"); - var userPrefix = ''; - if (inline) { - // assume that the change was made by the same user - commentHead.appendChild(currentDiv); - currentDiv.setAttribute("class", "bztw_inlinehistory"); - } else { - // the change was made by another user - if (!reachedEnd) { - var parentDiv = commentHead.parentNode; - if (parentDiv.previousElementSibling && - parentDiv.previousElementSibling.className.indexOf("bztw_history") >= 0) { - currentDiv = parentDiv.previousElementSibling; - } else { - parentDiv.parentNode.insertBefore(currentDiv, parentDiv); - } - } else { - var parentDiv = commentHead.parentNode; - if (parentDiv.nextElementSibling && - parentDiv.nextElementSibling.className.indexOf("bztw_history") >= 0) { - currentDiv = parentDiv.nextElementSibling; - } else { - parentDiv.parentNode.appendChild(currentDiv); - } - } - currentDiv.setAttribute("class", "bz_comment bztw_history"); - userPrefix += "" + - getUserName(trimContent(item[0])) + ": "; - } - // check to see if this is a flag setting - flagsFound = findFlag(item); - for (var idx = 0; idx < flagsFound.length; ++idx) { - var flag = flagsFound[idx]; - flagOccurrences[flag] = 'flag' + flagCounter; - if (inline) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", "flag" + flagCounter); - commentHead.insertBefore(anchor, commentHead.firstChild); - } else { - userPrefix += ''; - } - ++flagCounter; - } +// var historyItems = iframe.contentDocument.querySelectorAll('#bugzilla-body tr'); +// var cmtTimes = d.querySelectorAll('.bz_comment_time'); - var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); - if (inline) { - for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", attachmentFlagAnchors[idx]); - commentHead.insertBefore(anchor, commentHead.firstChild); - } - } else { - userPrefix += attachmentFlagAnchors.map(function(name) '').join(""); - } + // Sometimes the history will stack several changes together, + // and we'll want to append the data from the Nth item to the + // div created in N-1 + var i=0, j=0, flagsFound; + if (history) { + Array.forEach(history, function (item) { + processHistoryItem(cmtTimes, item); + }); + } + + handleEmptyCollapsedBoxes(document); - var ccOnly = (trimContent(item[2]) == 'CC'); - var ccPrefix = ccOnly ? '' : - '', - ccSuffix = ''; - var html = userPrefix + - ccPrefix + - transformType(trimContent(item[2]), d, trimContent(item[3]), - trimContent(item[4])) + ": " + - formatTransition(trimContent(item[3]), trimContent(item[4]), - trimContent(item[2]), d, iframe.contentDocument); - - var nextItemsCount = item[0].rowSpan; - for (var k = 1; k < nextItemsCount; ++k) { - ccOnly = false; - item = historyItems[++i].querySelectorAll("td") - ccPrefix = (trimContent(item[0]) == 'CC') ? - '' : ''; - // avoid showing a trailing semicolon if the previous entry - // wasn't a CC and this one is - var prefix = ccSuffix + ccPrefix; - // check to see if this is a flag setting - flagsFound = findFlag(item); - for (var idx = 0; idx < flagsFound.length; ++idx) { - var flag = flagsFound[idx]; - flagOccurrences[flag] = 'flag' + flagCounter; - if (inline) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", "flag" + flagCounter); - commentHead.insertBefore(anchor, commentHead.firstChild); - } else { - prefix += ''; - } - ++flagCounter; - } +// // Set the latest flag links if necessary +// for (var flagName in flagOccurrences) { +// flags[flagName].innerHTML = '' +// + flags[flagName].innerHTML + ''; +// } - var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); - if (inline) { - for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { - var anchor = d.createElement("a"); - anchor.setAttribute("name", attachmentFlagAnchors[idx]); - commentHead.insertBefore(anchor, commentHead.firstChild); - } - } else { - prefix += attachmentFlagAnchors.map(function(name) '').join(""); - } +// AttachmentFlagHandler.setupLinks(d); + // END OF load event handler - html += prefix + - transformType(trimContent(item[0]), d, trimContent(item[1]), - trimContent(item[2])) + ": " + - formatTransition(trimContent(item[1]), trimContent(item[2]), - trimContent(item[0]), d, iframe.contentDocument); - } - html += ccSuffix; - if (ccOnly) { - html = '
    ' + html + '
    '; - } else { - html = '
    ' + html + '
    '; - } - currentDiv.innerHTML += html; - break; - } +} + + +function processHistoryItem(commentTimes, itemRaw) { + var item = itemRaw.querySelectorAll("td"); + if (!item[1]) + return; + + var reachedEnd = false; + for (; j < commentTimes.length; j++) { + if (trimContent(item[1]) > trimContent(commentTimes[j])) { + if (j < commentTimes.length - 1) { + return; + } else { + reachedEnd = true; + } + } + + var commentHead = commentTimes[j].parentNode; + + var mainUser = commentHead.querySelector(".bz_comment_user a.email") + .href + .substr(7); + var user = trimContent(item[0]); + var mainTime = trimContent(commentTimes[j]); + var time = trimContent(item[1]); + var inline = (mainUser == user && time == mainTime); + + var currentDiv = d.createElement("div"); + var userPrefix = ''; + if (inline) { + // assume that the change was made by the same user + commentHead.appendChild(currentDiv); + currentDiv.setAttribute("class", "bztw_inlinehistory"); + } else { + // the change was made by another user + if (!reachedEnd) { + var parentDiv = commentHead.parentNode; + if (parentDiv.previousElementSibling && + parentDiv.previousElementSibling.className.indexOf("bztw_history") >= 0) { + currentDiv = parentDiv.previousElementSibling; + } else { + parentDiv.parentNode.insertBefore(currentDiv, parentDiv); } + } else { + var parentDiv = commentHead.parentNode; + if (parentDiv.nextElementSibling && + parentDiv.nextElementSibling.className.indexOf("bztw_history") >= 0) { + currentDiv = parentDiv.nextElementSibling; + } else { + parentDiv.parentNode.appendChild(currentDiv); + } + } + currentDiv.setAttribute("class", "bz_comment bztw_history"); + userPrefix += "" + + getUserName(trimContent(item[0])) + ": "; + } + // check to see if this is a flag setting + flagsFound = findFlag(item); + for (var idx = 0; idx < flagsFound.length; ++idx) { + var flag = flagsFound[idx]; + flagOccurrences[flag] = 'flag' + flagCounter; + if (inline) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", "flag" + flagCounter); + commentHead.insertBefore(anchor, commentHead.firstChild); + } else { + userPrefix += ''; + } + ++flagCounter; + } - handleEmptyCollapsedBoxes(d); + var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); + if (inline) { + for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", attachmentFlagAnchors[idx]); + commentHead.insertBefore(anchor, commentHead.firstChild); + } + } else { + userPrefix += attachmentFlagAnchors.map(function(name) '').join(""); + } - // Set the latest flag links if necessary - for (var flagName in flagOccurrences) { - flags[flagName].innerHTML = '' - + flags[flagName].innerHTML + ''; + var ccOnly = (trimContent(item[2]) == 'CC'); + var ccPrefix = ccOnly ? '' : + '', + ccSuffix = ''; + var html = userPrefix + + ccPrefix + + transformType(trimContent(item[2]), d, trimContent(item[3]), + trimContent(item[4])) + ": " + + formatTransition(trimContent(item[3]), trimContent(item[4]), + trimContent(item[2]), d, iframe.contentDocument); + + var nextItemsCount = item[0].rowSpan; + for (var k = 1; k < nextItemsCount; ++k) { + ccOnly = false; + item = historyItems[++i].querySelectorAll("td") + ccPrefix = (trimContent(item[0]) == 'CC') ? + '' : ''; + // avoid showing a trailing semicolon if the previous entry + // wasn't a CC and this one is + var prefix = ccSuffix + ccPrefix; + // check to see if this is a flag setting + flagsFound = findFlag(item); + for (var idx = 0; idx < flagsFound.length; ++idx) { + var flag = flagsFound[idx]; + flagOccurrences[flag] = 'flag' + flagCounter; + if (inline) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", "flag" + flagCounter); + commentHead.insertBefore(anchor, commentHead.firstChild); + } else { + prefix += ''; } + ++flagCounter; + } - AttachmentFlagHandler.setupLinks(d); - },true); - d.body.appendChild(iframe); + var attachmentFlagAnchors = AttachmentFlagHandler.handleItem(user, item); + if (inline) { + for (var idx = 0; idx < attachmentFlagAnchors.length; ++idx) { + var anchor = d.createElement("a"); + anchor.setAttribute("name", attachmentFlagAnchors[idx]); + commentHead.insertBefore(anchor, commentHead.firstChild); + } + } else { + prefix += attachmentFlagAnchors.map(function(name) '').join(""); + } - tbplbotSpamCollapser(d); + html += prefix + + transformType(trimContent(item[0]), d, trimContent(item[1]), + trimContent(item[2])) + ": " + + formatTransition(trimContent(item[1]), trimContent(item[2]), + trimContent(item[0]), d, iframe.contentDocument); + } + html += ccSuffix; + if (ccOnly) { + html = '
    ' + html + '
    '; + } else { + html = '
    ' + html + '
    '; + } + currentDiv.innerHTML += html; + break; + } } // =================================================== - var TransformValues = { linkifyURLs: function (str) { - return str.replace(/((https?|ftp)\:\/\/[\S]+)/g, '$1'); + return str.replace(/((https?|ftp)\:\/\/[\S]+)/g, '$1'); }, linkifyBugAndCommentNumbers: function (str) { - return str.replace(/(bug )(\d+) (comment )(\d+)/gi, '$1\n$2 $3\n$4'); + return str.replace(/(bug )(\d+) (comment )(\d+)/gi, '$1\n$2 $3\n$4'); }, linkifyCommentNumbers: function (str) { - return str.replace(/(comment (\d+))/gi, '$1'); + return str.replace(/(comment (\d+))/gi, '$1'); }, linkifyBugNumbers: function (str) { - return str.replace(/(bug (\d+))/gi, '$1'); + return str.replace(/(bug (\d+))/gi, '$1'); }, linkifyDependencies: function (str, type, doc, histDoc) { - switch (type) { - case "Blocks": - case "Depends on": - case "Duplicate": - str = str.replace(/\d+/g, function(str) { - var link = histDoc.querySelector("a[href='show_bug.cgi?id=" + str + "']"); - if (link) { - var class_ = ''; - if (/bz_closed/i.test(link.className)) { - class_ += 'bz_closed '; - } else if (/bztw_unconfirmed/i.test(link.className)) { - class_ += 'bztw_unconfirmed '; - } - var parent = link.parentNode; - if (parent) { - if (parent.tagName.toLowerCase() == "i") { - class_ += 'bztw_unconfirmed '; - } - if (/bz_closed/i.test(parent.className)) { - class_ += 'bz_closed '; - } - } - str = applyClass(class_, - '' + htmlEncode(str) + ''); - } - return str; - }); - } - return str; + switch (type) { + case "Blocks": + case "Depends on": + case "Duplicate": + str = str.replace(/\d+/g, function(str) { + var link = histDoc.querySelector("a[href='show_bug.cgi?id=" + str + "']"); + if (link) { + var class_ = ''; + if (/bz_closed/i.test(link.className)) { + class_ += 'bz_closed '; + } else if (/bztw_unconfirmed/i.test(link.className)) { + class_ += 'bztw_unconfirmed '; + } + var parent = link.parentNode; + if (parent) { + if (parent.tagName.toLowerCase() == "i") { + class_ += 'bztw_unconfirmed '; + } + if (/bz_closed/i.test(parent.className)) { + class_ += 'bz_closed '; + } + } + str = applyClass(class_, + '' + htmlEncode(str) + ''); + } + return str; + }); + } + return str; } }; // =============================================================================== function transform(str, type, doc, histDoc) { - for (var funcname in TransformValues) { - var func = TransformValues[funcname]; - str = func.call(null, str, type, doc, histDoc); - } - return str + for (var funcname in TransformValues) { + var func = TransformValues[funcname]; + str = func.call(null, str, type, doc, histDoc); + } + return str } var TransformTypes = { linkifyAttachments: function (str, doc) { - return str.replace(/(Attachment #(\d+))/g, function (str, x, id) { - var link = doc.querySelector("a[href='attachment.cgi?id=" + id + "']"); - if (link) { - var class_ = ''; - if (/bz_obsolete/i.test(link.className)) { - class_ += 'bz_obsolete '; - } - var parent = link.parentNode; - if (parent && /bz_obsolete/i.test(parent.className)) { - class_ += 'bz_obsolete '; - } - if (link.querySelector(".bz_obsolete")) { - class_ += 'bz_obsolete '; - } - str = applyClass(class_, - '' + htmlEncode(str) + ''); - } - return str; - }); + return str.replace(/(Attachment #(\d+))/g, function (str, x, id) { + var link = doc.querySelector("a[href='attachment.cgi?id=" + id + "']"); + if (link) { + var class_ = ''; + if (/bz_obsolete/i.test(link.className)) { + class_ += 'bz_obsolete '; + } + var parent = link.parentNode; + if (parent && /bz_obsolete/i.test(parent.className)) { + class_ += 'bz_obsolete '; + } + if (link.querySelector(".bz_obsolete")) { + class_ += 'bz_obsolete '; + } + str = applyClass(class_, + '' + htmlEncode(str) + ''); + } + return str; + }); }, changeDependencyLinkTitles: function (str, doc, old, new_) { - switch (str) { - case "Blocks": - case "Depends on": - if (old.length && !new_.length) { // if the dependency was removed - str = "No longer " + str[0].toLowerCase() + str.substr(1); - } - break; + switch (str) { + case "Blocks": + case "Depends on": + if (old.length && !new_.length) { // if the dependency was removed + str = "No longer " + str[0].toLowerCase() + str.substr(1); } - return str; + break; + } + return str; } }; // ======================================================================= function transformType(str, doc, old, new_) { - for (var funcname in TransformTypes) { - var func = TransformTypes[funcname]; - str = func.call(null, str, doc, old, new_); - } - return str; + for (var funcname in TransformTypes) { + var func = TransformTypes[funcname]; + str = func.call(null, str, doc, old, new_); + } + return str; } // new is a keyword, which makes this function uglier than I'd like function formatTransition(old, new_, type, doc, histDoc) { - if (old.length) { - old = transform(htmlEncode(old), type, doc, histDoc); - var setOldStyle = true; - switch (type) { - case "Blocks": - case "Depends on": - setOldStyle = false; - break; - } - if (setOldStyle) { - old = '' + old + ''; - } - } - if (new_.length) { - new_ = '' + transform(htmlEncode(new_), type, doc, histDoc) + ''; + if (old.length) { + old = transform(htmlEncode(old), type, doc, histDoc); + var setOldStyle = true; + switch (type) { + case "Blocks": + case "Depends on": + setOldStyle = false; + break; } - var mid = ''; - if (old.length && new_.length) { - mid = ' '; + if (setOldStyle) { + old = '' + old + ''; } - return old + mid + new_; + } + if (new_.length) { + new_ = '' + transform(htmlEncode(new_), type, doc, histDoc) + ''; + } + var mid = ''; + if (old.length && new_.length) { + mid = ' '; + } + return old + mid + new_; } // ========================================================================= function trimContent(el) { - return el.textContent.trim(); + return el.textContent.trim(); } function AttachmentFlag(flag) { - for (var name in flag) - this[name] = flag[name]; + for (var name in flag) + this[name] = flag[name]; } AttachmentFlag.prototype = { equals: function(flag) { - if (this.type != flag.type || - this.name != flag.name || - this.setter != flag.setter || - ("requestee" in this && !("requestee" in flag)) || - ("requestee" in flag && !("requestee" in this))) - return false; - return this.requestee == flag.requestee; + if (this.type != flag.type || + this.name != flag.name || + this.setter != flag.setter || + ("requestee" in this && !("requestee" in flag)) || + ("requestee" in flag && !("requestee" in this))) + return false; + return this.requestee == flag.requestee; } }; @@ -537,167 +697,155 @@ function quicksearchHandler(doc) { } function AttachmentFlagHandlerCtor() { - this._db = {}; - this._interestingFlags = {}; + this._db = {}; + this._interestingFlags = {}; } AttachmentFlagHandlerCtor.prototype = { determineInterestingFlags: function (doc) { - var table = doc.getElementById("attachment_table"); - if (!table) - return; - var rows = table.querySelectorAll("tr"); - for (var i = 0; i < rows.length; ++i) { - var item = rows[i].querySelectorAll("td"); - if (item.length != 3 || - item[1].className.indexOf("bz_attach_flags") < 0 || - trimContent(item[1]) == "no flags") - continue; - // get the ID of the attachment - var link = item[0].querySelector("a"); - if (!link) - continue; - var match = this._reAttachmentHref.exec(link.href); + var table = doc.getElementById("attachment_table"); + if (!table) + return; + var rows = table.querySelectorAll("tr"); + for (var i = 0; i < rows.length; ++i) { + var item = rows[i].querySelectorAll("td"); + if (item.length != 3 || + item[1].className.indexOf("bz_attach_flags") < 0 || + trimContent(item[1]) == "no flags") + continue; + // get the ID of the attachment + var link = item[0].querySelector("a"); + if (!link) + continue; + var match = this._reAttachmentHref.exec(link.href); + if (match) { + var attachmentID = match[1]; + if (!(attachmentID in this._interestingFlags)) { + this._interestingFlags[attachmentID] = []; + } + for (var el = item[1].firstChild; el.nextSibling; el = el.nextSibling) { + if (el.nodeType != el.TEXT_NODE) + continue; + var text = trimContent(el).replace('\u2011', '-', 'g'); + if (!text) + continue; + match = this._reParseInterestingFlag.exec(text); if (match) { - var attachmentID = match[1]; - if (!(attachmentID in this._interestingFlags)) { - this._interestingFlags[attachmentID] = []; + var flag = {}; + flag.setter = match[1]; + flag.name = match[2]; + if (match[4] == "+" || match[4] == "-") { + flag.type = match[4]; + } else { + flag.type = "?"; + if (match[7]) { + flag.requestee = match[7]; } - var text = ""; - var previousText = ""; - var previousEl = null; - for (var el = item[1].firstChild; el.nextSibling; el = el.nextSibling) { - var thisText = trimContent(el).replace('\u2011', '-', 'g'); - text += thisText; - if (this._reParsePartToLinkify.test(thisText)) { - previousText = thisText; - previousEl = el; - } - if (el.nodeType != el.ELEMENT_NODE || - el.localName.toLowerCase() != "br") - continue; - match = this._reParseInterestingFlag.exec(text); - if (match) { - var flag = {}; - flag.setter = match[1]; - flag.name = match[2]; - if (match[4] == "+" || match[4] == "-") { - flag.type = match[4]; - } else { - flag.type = "?"; - if (match[7]) { - flag.requestee = match[7]; - } - } - - // always show the obsolete attachments with a + flag - if (flag.type == "+") { - var parent = link.parentNode; - while (parent) { - if (parent.tagName.toLowerCase() == "tr") { - if (/bz_tr_obsolete/i.test(parent.className)) { - parent.className += " bztw_plusflag"; - } - break; - } - parent = parent.parentNode; - } - } - - // try to put the flag name and type part in a span - // which we will - // use in setupLinks to inject links into. - match = this._reLinkifyInterestingFlag.exec(previousText); - if (match) { - previousEl.textContent = match[1]; - if (match[3]) { - var textNode = doc.createTextNode(match[3]); - previousEl.parentNode.insertBefore(textNode, previousEl.nextSibling); - } - var span = doc.createElement("span"); - span.textContent = match[2]; - previousEl.parentNode.insertBefore(span, previousEl.nextSibling); - - flag.placeholder = span; - } + } - this._interestingFlags[attachmentID].push(new AttachmentFlag(flag)); + // always show the obsolete attachments with a + flag + if (flag.type == "+") { + var parent = link.parentNode; + while (parent) { + if (parent.tagName.toLowerCase() == "tr") { + if (/bz_tr_obsolete/i.test(parent.className)) { + parent.className += " bztw_plusflag"; } - text = ""; - previousText = ""; - previousEl = null; + break; + } + parent = parent.parentNode; } + } + + // try to put the flag name and type part in a span + // which we will + // use in setupLinks to inject links into. + match = this._reLinkifyInterestingFlag.exec(text); + if (match) { + el.textContent = match[1]; + if (match[3]) { + var textNode = doc.createTextNode(match[3]); + el.parentNode.insertBefore(textNode, el.nextSibling); + } + var span = doc.createElement("span"); + span.textContent = match[2]; + el.parentNode.insertBefore(span, el.nextSibling); + + flag.placeholder = span; + } + + this._interestingFlags[attachmentID].push(new AttachmentFlag(flag)); } + } } + } }, handleItem: function (name, item) { - var anchorsCreated = []; - var base = item[4] ? 2 : 0; - var what = trimContent(item[base]); - var match = this._reAttachmentFlagName.exec(what); - if (match) { - var id = match[1]; - if (!(id in this._db)) { - this._db[id] = []; - } - name = name.split('@')[0]; // convert the name to the fraction - // before the @ - var added = this._parseData(name, trimContent(item[base + 2])); - for (var i = 0; i < added.length; ++i) { - var flag = added[i]; - if (!(id in this._interestingFlags)) - continue; - for (var j = 0; j < this._interestingFlags[id].length; ++j) { - // Take care to not assign an anchor to a flag which already has one - if (flag.equals(this._interestingFlags[id][j]) && - !("anchor" in this._interestingFlags[id][j])) { - // found an interesting flag - this._interestingFlags[id][j].anchor = this.anchorName; - anchorsCreated.push(this.anchorName); - this._counter++; - break; - } - } + var anchorsCreated = []; + var base = item[4] ? 2 : 0; + var what = trimContent(item[base]); + var match = this._reAttachmentFlagName.exec(what); + if (match) { + var id = match[1]; + if (!(id in this._db)) { + this._db[id] = []; + } + name = name.split('@')[0]; // convert the name to the fraction + // before the @ + var added = this._parseData(name, trimContent(item[base + 2])); + for (var i = 0; i < added.length; ++i) { + var flag = added[i]; + if (!(id in this._interestingFlags)) + continue; + for (var j = 0; j < this._interestingFlags[id].length; ++j) { + if (flag.equals(this._interestingFlags[id][j])) { + // found an interesting flag + this._interestingFlags[id][j].anchor = this.anchorName; + anchorsCreated.push(this.anchorName); + this._counter++; + break; } + } } - return anchorsCreated; + } + return anchorsCreated; }, setupLinks: function (doc) { - for (var id in this._interestingFlags) { - for (var i = 0; i < this._interestingFlags[id].length; ++i) { - var flag = this._interestingFlags[id][i]; - if ("placeholder" in flag && - "anchor" in flag) { - var link = doc.createElement("a"); - link.href = "#" + flag.anchor; - link.textContent = flag.placeholder.textContent; - flag.placeholder.replaceChild(link, flag.placeholder.firstChild); - } - } + for (var id in this._interestingFlags) { + for (var i = 0; i < this._interestingFlags[id].length; ++i) { + var flag = this._interestingFlags[id][i]; + if ("placeholder" in flag && + "anchor" in flag) { + var link = doc.createElement("a"); + link.href = "#" + flag.anchor; + link.textContent = flag.placeholder.textContent; + flag.placeholder.replaceChild(link, flag.placeholder.firstChild); + } } + } }, _parseData: function (name, str) { - var items = str.replace('\u2011', '-', 'g').split(', '), flags = []; - for (var i = 0; i < items.length; ++i) { - if (!items[i].length) - continue; + var items = str.replace('\u2011', '-', 'g').split(', '), flags = []; + for (var i = 0; i < items.length; ++i) { + if (!items[i].length) + continue; - var match = this._reParseRequest.exec(items[i]); - if (match) { - var flag = {}; - flag.name = match[1]; - flag.setter = name; - if (match[4]) { - flag.requestee = match[4]; - } - flag.type = match[2]; - flags.push(new AttachmentFlag(flag)); - } + var match = this._reParseRequest.exec(items[i]); + if (match) { + var flag = {}; + flag.name = match[1]; + flag.setter = name; + if (match[4]) { + flag.requestee = match[4]; + } + flag.type = match[2]; + flags.push(new AttachmentFlag(flag)); } - return flags; + } + return flags; }, _counter: 1, get anchorName() { - return "attachflag" + this._counter; + return "attachflag" + this._counter; }, _reParseRequest: /^(.+)([\?\-\+])(\((.+)@.+\))?$/, _reParsePartToLinkify: /^\s*:\s+.+[\-\+\?](\s*\()?\s*$/, @@ -708,100 +856,100 @@ AttachmentFlagHandlerCtor.prototype = { }; function CheckinCommentCtor() { - this.bugNumber = null; - this.summarySpan = null; - this.checkinFlags = ""; + this.bugNumber = null; + this.summarySpan = null; + this.checkinFlags = ""; } CheckinCommentCtor.prototype = { - initialize: function(doc, flags) { - this.bugNumber = getBugNo(doc); - var summarySpan = doc.getElementById("short_desc_nonedit_display"); - if (summarySpan) { + initialize: function(doc, flags) { + this.bugNumber = getBugNumber(doc); + var summarySpan = doc.getElementById("short_desc_nonedit_display"); + if (summarySpan) { this.summary = summarySpan.textContent; - } - var checkinFlagsMap = {}; - for (var id in flags) { + } + var checkinFlagsMap = {}; + for (var id in flags) { for (var i = 0; i < flags[id].length; ++i) { - var flag = flags[id][i]; - if (flag.type == "+") { - var name = flag.name; - if (name == "review") { - name = "r"; - } else if (name == "superreview") { - name = "sr"; - } else if (name == "ui-review") { - name = "ui-r"; - } else if (name == "feedback") { - name = "f"; - } - if (!(name in checkinFlagsMap)) { - checkinFlagsMap[name] = {}; - } - checkinFlagsMap[name][flag.setter]++; + var flag = flags[id][i]; + if (flag.type == "+") { + var name = flag.name; + if (name == "review") { + name = "r"; + } else if (name == "superreview") { + name = "sr"; + } else if (name == "ui-review") { + name = "ui-r"; + } else if (name == "feedback") { + name = "f"; + } + if (!(name in checkinFlagsMap)) { + checkinFlagsMap[name] = {}; } + checkinFlagsMap[name][flag.setter]++; + } } - } - var flagsOrdered = []; - for (var name in checkinFlagsMap) { + } + var flagsOrdered = []; + for (var name in checkinFlagsMap) { flagsOrdered.push(name); - } - flagsOrdered.sort(function (a, b) { + } + flagsOrdered.sort(function (a, b) { function convertToNumber(x) { - switch (x) { - case "f": - return -4; - case "r": - return -3; - case "sr": - return -2; - case "ui-r": - return -1; - default: - return 0; - } + switch (x) { + case "f": + return -4; + case "r": + return -3; + case "sr": + return -2; + case "ui-r": + return -1; + default: + return 0; + } } var an = convertToNumber(a); var bn = convertToNumber(b); if (an == 0 && bn == 0) { - return a < b ? -1 : (a = b ? 0 : 1); + return a < b ? -1 : (a = b ? 0 : 1); } else { - return an - bn; + return an - bn; } - }); - var checkinFlags = []; - for (var i = 0; i < flagsOrdered.length; ++i) { + }); + var checkinFlags = []; + for (var i = 0; i < flagsOrdered.length; ++i) { var name = flagsOrdered[i]; var flag = name + "="; var setters = []; for (var setter in checkinFlagsMap[name]) { - setters.push(setter); + setters.push(setter); } flag += setters.join(","); checkinFlags.push(flag); - } - this.checkinFlags = checkinFlags.join(" "); - if (this.isValid()) { - var div = doc.createElement("div"); - div.setAttribute("style", "display: none;"); - div.id = "__bz_tw_checkin_comment"; - div.appendChild(doc.createTextNode(this.toString())); - doc.body.appendChild(div); - } - }, - isValid: function() { + } + this.checkinFlags = checkinFlags.join(" "); + if (this.isValid()) { + var div = doc.createElement("div"); + div.setAttribute("style", "display: none;"); + div.id = "__bz_tw_checkin_comment"; + div.appendChild(doc.createTextNode(this.toString())); + doc.body.appendChild(div); + } + }, + isValid: function() { return this.bugNumber != null && - this.summary != null; - }, - toString: function() { - if (!this.isValid()) { + this.summary != null; + }, + toString: function() { + if (!this.isValid()) { return ""; - } - var message = "Bug " + this.bugNumber + " - " + this.summary; - if (this.checkinFlags.length) { + } + var message = "Bug " + this.bugNumber + " - " + this.summary; + if (this.checkinFlags.length) { message += "; " + this.checkinFlags; + } + return message; } - return message; - } }; function DataStoreCtor(doc) { @@ -820,7 +968,7 @@ function DataStoreCtor(doc) { var count = window.localStorage.length; if (count > 0) { if (window.confirm("You currently have data stored for " + count + " bugs.\n\n" + - "Are you sure you want to clear this data? This action cannot be undone.")) { + "Are you sure you want to clear this data? This action cannot be undone.")) { window.localStorage.clear(); } } else { @@ -829,110 +977,110 @@ function DataStoreCtor(doc) { } var script = doc.createElement("script"); script.appendChild(doc.createTextNode(visualizeStoredData.toSource() + - clearStoredData.toSource() + - htmlEncode.toSource())); + clearStoredData.toSource() + + htmlEncode.toSource())); doc.body.appendChild(script); this.initialize(doc); } DataStoreCtor.prototype = { - initialize: function(doc) { - this.bugNumber = getBugNo(doc); - var data = this._ensureEntry(this.bugNumber, this.data); - // last visited date - data.visitedTime = (new Date()).getTime(); - // last comment count - data.commentCount = doc.querySelectorAll(".bz_comment").length; - // last status of bug flags - var flags = this._ensureEntry("flags", data); - var flagRows = doc.querySelectorAll("#flags tr"); - for (var i = 0; i < flagRows.length; ++i) { - var flagCols = flagRows[i].querySelectorAll("td"); - if (flagCols.length != 3) { - continue; - } - var flagName = trimContent(flagCols[1]); - var flagValue = flagCols[2].querySelector("select"); - if (flagValue) { - flagValue = flagValue.value; - } else { - continue; - } - flags[flagName] = flagValue; - } - flagRows = doc.querySelectorAll(".field_label[id^=field_label_cf_]"); - for (var i = 0; i < flagRows.length; ++i) { - var flagName = trimContent(flagRows[i]).replace(/:$/, ""); - var flagValue = flagRows[i].parentNode.querySelector("select"); - if (flagValue) { - flagValue = flagValue.value; - } else { - continue; + initialize: function(doc) { + this.bugNumber = getBugNumber(doc); + var data = this._ensureEntry(this.bugNumber, this.data); + // last visited date + data.visitedTime = (new Date()).getTime(); + // last comment count + data.commentCount = doc.querySelectorAll(".bz_comment").length; + // last status of bug flags + var flags = this._ensureEntry("flags", data); + var flagRows = doc.querySelectorAll("#flags tr"); + for (var i = 0; i < flagRows.length; ++i) { + var flagCols = flagRows[i].querySelectorAll("td"); + if (flagCols.length != 3) { + continue; + } + var flagName = trimContent(flagCols[1]); + var flagValue = flagCols[2].querySelector("select"); + if (flagValue) { + flagValue = flagValue.value; + } else { + continue; + } + flags[flagName] = flagValue; } - flags[flagName] = flagValue; - } - // last attachments - var attachmentTable = doc.getElementById("attachment_table"); - var attachmentRows = attachmentTable.querySelectorAll("tr"); - for (var i = 0; i < attachmentRows.length; ++i) { - var attachmentCells = attachmentRows[i].querySelectorAll("td"); - if (attachmentCells.length != 3) { - continue; + flagRows = doc.querySelectorAll(".field_label[id^=field_label_cf_]"); + for (var i = 0; i < flagRows.length; ++i) { + var flagName = trimContent(flagRows[i]).replace(/:$/, ""); + var flagValue = flagRows[i].parentNode.querySelector("select"); + if (flagValue) { + flagValue = flagValue.value; + } else { + continue; + } + flags[flagName] = flagValue; } - var link = attachmentCells[0].querySelector("a"); - var match = this._reAttachmentHref.exec(link.href); - if (match) { - var attachmentID = match[1]; - var attachment = this._ensureEntry("attachments", data); - var attachmentFlags = this._ensureArray(attachmentID, attachment); - for (var el = attachmentCells[1].firstChild; el.nextSibling; el = el.nextSibling) { - if (el.nodeType != el.TEXT_NODE) { - continue; - } - var text = trimContent(el); - if (!text) { - continue; - } - match = this._reParseInterestingFlag.exec(text); - if (match) { - var flag = {}; - flag.setter = match[1]; - flag.name = match[2]; - if (match[4] == "+" || match[4] == "-") { + // last attachments + var attachmentTable = doc.getElementById("attachment_table"); + var attachmentRows = attachmentTable.querySelectorAll("tr"); + for (var i = 0; i < attachmentRows.length; ++i) { + var attachmentCells = attachmentRows[i].querySelectorAll("td"); + if (attachmentCells.length != 3) { + continue; + } + var link = attachmentCells[0].querySelector("a"); + var match = this._reAttachmentHref.exec(link.href); + if (match) { + var attachmentID = match[1]; + var attachment = this._ensureEntry("attachments", data); + var attachmentFlags = this._ensureArray(attachmentID, attachment); + for (var el = attachmentCells[1].firstChild; el.nextSibling; el = el.nextSibling) { + if (el.nodeType != el.TEXT_NODE) { + continue; + } + var text = trimContent(el); + if (!text) { + continue; + } + match = this._reParseInterestingFlag.exec(text); + if (match) { + var flag = {}; + flag.setter = match[1]; + flag.name = match[2]; + if (match[4] == "+" || match[4] == "-") { flag.type = match[4]; - } else { + } else { flag.type = "?"; if (match[7]) { - flag.requestee = match[7]; + flag.requestee = match[7]; } + } + attachmentFlags.push(flag); } - attachmentFlags.push(flag); } } } - } - // Write data to storage - for (var key in this.data) { - this._ensure(key, this.storage, JSON.stringify(this.data[key])); - } - }, - _ensure: function(entry, obj, val) { - if (obj.toString().indexOf("[object Storage") >= 0) { - obj.setItem(entry, val); - } else { - if (typeof obj[entry] == "undefined") - obj[entry] = val; - return obj[entry]; - } - }, - _ensureEntry: function(entry, obj) { - return this._ensure(entry, obj, {}); - }, - _ensureArray: function(entry, obj) { - return this._ensure(entry, obj, []); - }, - _reParseInterestingFlag: /^(.+):\s+(.+)(([\-\+])|\?(\s+(\((.+)\)))?)$/, - _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i + // Write data to storage + for (var key in this.data) { + this._ensure(key, this.storage, JSON.stringify(this.data[key])); + } + }, + _ensure: function(entry, obj, val) { + if (obj.toString().indexOf("[object Storage") >= 0) { + obj.setItem(entry, val); + } else { + if (typeof obj[entry] == "undefined") + obj[entry] = val; + return obj[entry]; + } + }, + _ensureEntry: function(entry, obj) { + return this._ensure(entry, obj, {}); + }, + _ensureArray: function(entry, obj) { + return this._ensure(entry, obj, []); + }, + _reParseInterestingFlag: /^(.+):\s+(.+)(([\-\+])|\?(\s+(\((.+)\)))?)$/, + _reAttachmentHref: /attachment\.cgi\?id=(\d+)$/i }; @@ -946,37 +1094,37 @@ function getUserName(doc) { } function handleEmptyCollapsedBoxes(doc) { - // first, try to get the display style of a CC field (any would do) - var historyBoxes = doc.querySelectorAll(".bztw_history"); - for (var i = 0; i < historyBoxes.length; ++i) { - var box = historyBoxes[i]; - for (var j = 0; j < box.childNodes.length; ++j) { - var child = box.childNodes[j], found = true; - if (child.nodeType != child.ELEMENT_NODE) - continue; - if (child.className == "sep") { - // separators are insignificant - continue; - } else if (!/bztw_cc/.test(child.className)) { - found = false; - break; - } - } - if (found) { - box.className += " bztw_cc"; - } + // first, try to get the display style of a CC field (any would do) + var historyBoxes = doc.querySelectorAll(".bztw_history"); + for (var i = 0; i < historyBoxes.length; ++i) { + var box = historyBoxes[i]; + for (var j = 0; j < box.childNodes.length; ++j) { + var child = box.childNodes[j], found = true; + if (child.nodeType != child.ELEMENT_NODE) + continue; + if (child.className == "sep") { + // separators are insignificant + continue; + } else if (!/bztw_cc/.test(child.className)) { + found = false; + break; + } } + if (found) { + box.className += " bztw_cc"; + } + } } function applyClass(class_, html) { - return '' + html + ''; + return '' + html + ''; } function htmlEncode(str) { - return str.replace('&', '&', 'g') - .replace('<', '<', 'g') - .replace('>', '>', 'g') - .replace('"', '"', 'g'); + return str.replace('&', '&', 'g') + .replace('<', '<', 'g') + .replace('>', '>', 'g') + .replace('"', '"', 'g'); } function tbplbotSpamCollapser(d) { @@ -994,9 +1142,9 @@ function tbplbotSpamCollapser(d) { var comment = comments[i]; try { if (comment.querySelector(".bz_comment_user a.email").href.substr(7) == - "tbplbot@gmail.com") { + "tbplbot@gmail.com") { win.collapse_comment(comment.querySelector(".bz_collapse_comment"), - comment.querySelector(".bz_comment_text")); + comment.querySelector(".bz_comment_text")); } } catch (e) { continue; @@ -1009,5 +1157,3 @@ function tbplbotSpamCollapser(d) { li.appendChild(a); collapseExpandBox.appendChild(li); } - -tweakBugzilla(document); diff --git a/lib/libbugzilla.js b/lib/libbugzilla.js index c85d331..aa2d0b7 100644 --- a/lib/libbugzilla.js +++ b/lib/libbugzilla.js @@ -40,7 +40,7 @@ function log(msg) { /** * 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 @@ -57,7 +57,7 @@ function parseXMLfromString (inStuff) { /** * 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. - * + * * This is a slow variant for bugs other than actual window */ function getRealBugNoSlow(bugNo, location, callback) { @@ -144,10 +144,10 @@ exports.changeJSONURL = function changeJSONURL() { }; /** - * + * * libbz.getInstalledPackages(msg.data, function (pkgsMsg) { * worker.postMessage(pkgsMsg); - * + * * locationLoginObj: { location: window.location.href, login: getLogin() } */ exports.getInstalledPackages = function getInstalledPackages(locationLoginObj, callback) { @@ -288,36 +288,63 @@ exports.createUpstreamBug = function createUpstreamBug(urlStr, subject, comment) exports.makeXMLRPCCall = function makeXMLRPCCall(url, login, method, params, callback) { var urlObj = urlMod.URL(url); getPassword(login, - urlObj.schema + "://" + urlObj.host, - function (passwObj) { - if (!passwObj.password) { - // TODO this should happen, only when user presses Escape in password - // prompt - return null; - } + urlObj.schema + "://" + urlObj.host, + function (passwObj) { + if (!passwObj.password) { + // TODO this should happen, only when user presses Escape in password + // prompt + return null; + } - var msg = new xrpc.XMLRPCMessage(method); - params.forEach(function (par) { - msg.addParameter(par); - }); - msg.addParameter(login); - msg.addParameter(passwObj.password); - - Request({ - url: url, - onComplete: function(response) { - if (response.status == 200) { - var resp = parseXMLfromString(response.text); - callback(resp.toXMLString()); - } - }, - content: msg.xml(), - contentType: "text/xml" - }).post(); - } + var msg = new xrpc.XMLRPCMessage(method); + params.forEach(function (par) { + msg.addParameter(par); + }); + msg.addParameter(login); + msg.addParameter(passwObj.password); + + Request({ + url: url, + onComplete: function(response) { + if (response.status == 200) { + var resp = parseXMLfromString(response.text); + callback(resp.toXMLString()); + } + }, + content: msg.xml(), + contentType: "text/xml" + }).post(); + } ); }; +// Make a JSONL-RPC call ... most of the business logic should stay in the +// content script +// http://json-rpc.org/wd/JSON-RPC-1-1-WD-20060807.html +exports.makeJSONRPCCall = function makeJSONRPCCall(url, method, params, callback) { + +// {"version":"1.1", "method":"Bug.history", "params":{ "ids":[12345] } } + var msg = { + "version": "1.1", + "method": method, + "params": params + }; + + console.myDebug("makeJSONRPCCall: out = " + JSON.stringify(msg)); + + Request({ + url: url, + onComplete: function(response) { + if (response.status == 200) { + console.myDebug("makeJSONRPCCall: in = " + response.text); + callback(response.json.result); + } + }, + content: JSON.stringify(msg), + contentType: "application/json" + }).post(); +}; + exports.initialize = function initialize(config, callback) { var prefName = BTSPrefNS+"JSONURL"; var urlStr = ""; diff --git a/lib/main.js b/lib/main.js index c7fe2fd..302dda8 100644 --- a/lib/main.js +++ b/lib/main.js @@ -99,6 +99,15 @@ var messageHandler = exports.messageHandler = function messageHandler( ret)); }); break; + case "MakeJSONRPCall": + // url, login, method, params, callback + libbz + .makeJSONRPCCall(msg.data.url, msg.data.method, + msg.data.params, function(ret) { + worker.postMessage(new Message(msg.data.callRPC, + ret)); + }); + break; case "GetURL": libbz.getURL(msg.data.url, function(stuff) { @@ -123,7 +132,7 @@ var contentScriptLibraries = [ self.data.url("lib/util.js"), self.data.url("lib/jumpNextBug.js"), self.data.url("lib/queries.js"), - self.data.url("lib/preprocessDuplicates.js"), + self.data.url("tweaks/preprocessDuplicates.js"), self.data.url("tweaks/viewSource.js"), self.data.url("lib/color.js"), self.data.url("tweaks/addNewLinks.js"), -- cgit From 5371dac76e4cfed85033ae0cf161d7ad2dbfb83f Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 29 Apr 2011 13:38:04 +0200 Subject: Incompatibility bits. * global onMessage is not chic anymore, replacing with self.on handler. * filterByRegexp returns string and could return null. Make sure we can survive it. --- data/lib/bzpage.js | 4 ++-- data/lib/otherButtons.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/lib/bzpage.js b/data/lib/bzpage.js index 02c8e3c..76dd1a7 100644 --- a/data/lib/bzpage.js +++ b/data/lib/bzpage.js @@ -21,7 +21,7 @@ var equivalentComponents = null; /** * central handler processing messages from the main script. */ -onMessage = function onMessage(msg) { +self.on('message', function onMessage(msg) { console.log("onMessage - incoming : msg.cmd = " + msg.cmd); switch (msg.cmd) { case "ReloadThePage": @@ -50,7 +50,7 @@ onMessage = function onMessage(msg) { console.error("Error: unknown RPC call " + msg.toSource()); } } -}; +}); /** * @param cmd diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js index ab8ec35..0e7b408 100644 --- a/data/lib/otherButtons.js +++ b/data/lib/otherButtons.js @@ -78,7 +78,7 @@ function addingEmbelishments(list) { var maintCCAddr = ""; if (constantData.CCmaintainer) { maintCCAddr = filterByRegexp(constantData.CCmaintainer, - getComponent())[0]; // filterByRegexp returns array, not string + getComponent()); // filterByRegexp returns string, not array, now } // we should make visible whether maintCCAddr is in CCList -- cgit From 5f0cadb2b9b2929c63f2f35de14b63578efcc595 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 29 Apr 2011 13:42:01 +0200 Subject: There is no in 4.0 BZ and it is not necessary anyway. --- data/lib/bzpage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/lib/bzpage.js b/data/lib/bzpage.js index 76dd1a7..ca3993a 100644 --- a/data/lib/bzpage.js +++ b/data/lib/bzpage.js @@ -415,7 +415,7 @@ function startup() { // to be generally much more stable (even with other bugzillas, e.g. // b.gnome.org) // then some getElementById. - var commentArea = document.getElementsByName("add_comment")[0].parentNode; + var commentArea = document.getElementsByClassName("bz_section_additional_comments")[0]; if (commentArea) { var brElementPlacer = commentArea.getElementsByTagName("br"); brElementPlacer = brElementPlacer[0]; -- cgit From 08194f2c04e1831a8a6c50b8290615889a5080a3 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Sun, 1 May 2011 20:50:24 +0200 Subject: Comment away activation of tweakBugzilla for 0.99 release. --- data/lib/bzpage.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/lib/bzpage.js b/data/lib/bzpage.js index ca3993a..d957bd3 100644 --- a/data/lib/bzpage.js +++ b/data/lib/bzpage.js @@ -316,9 +316,9 @@ function generateButtons (pkgs, kNodes) { RHBZinit(); } - if (tweakBugzilla) { - tweakBugzilla(document, constantData); - } +// if (tweakBugzilla) { +// tweakBugzilla(document, constantData); +// } } function setConfigurationButton () { -- cgit From 92421b51663ce34939fee936ddcbeec91a67bced Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Mon, 2 May 2011 21:59:55 +0200 Subject: "all" keyword in enabledPackages configuration didn't work. Bad use of Array.slice. Fixes #89 --- lib/libbugzilla.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/libbugzilla.js b/lib/libbugzilla.js index aa2d0b7..a1792ea 100644 --- a/lib/libbugzilla.js +++ b/lib/libbugzilla.js @@ -171,11 +171,10 @@ exports.getInstalledPackages = function getInstalledPackages(locationLoginObj, c } } - var allIdx = null; if ((allIdx = enabledPackages.indexOf("all")) != -1) { - enabledPackages = enabledPackages.splice(allIdx, - Object.keys(config.gJSONData.commentPackages)); + enabledPackages.splice(allIdx, 1); + enabledPackages = enabledPackages.concat(Object.keys(config.gJSONData.commentPackages)); } // TODO To be decided, whether we cannot just eliminate packages in -- cgit From 0b92c971cd6887ff7386c0e2a7577440429d47f6 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Mon, 2 May 2011 23:36:30 +0200 Subject: New release ... 0.99 --- Makefile | 2 +- package.json | 2 +- update.rdf | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 6087a94..1bbdd03 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ local-install: bugzilla-triage.xpi rsync -av bugzilla-triage.xpi $(WEBDIR) rsync -av jsons/Config_data.json $(WEBDIR) -bugzilla-triage.xpi: package.json lib/*.js docs/* +bugzilla-triage.xpi: package.json lib/*.js cfx xpi ;\ unzip -qqo bugzilla-triage.xpi install.rdf ;\ sed -i -e \ diff --git a/package.json b/package.json index 28ecc69..5abbd52 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "description": "Additional buttons and other function helping in the triage on bugzilla", "author": "Matej Cepl (http://matej.ceplovi.cz)", "license": "MIT/X11 (http://opensource.org/licenses/mit-license.php) and MPL", - "version": "0.98", + "version": "0.99", "contributors": [ "Ehsan Akhgari (http://ehsanakhgari.org/) ", "Johnathan Nightingale (http://johnath.com) ", diff --git a/update.rdf b/update.rdf index 8938170..1499e88 100644 --- a/update.rdf +++ b/update.rdf @@ -367,6 +367,21 @@ xmlns:em="http://www.mozilla.org/2004/em-rdf#"> +
  • + + 0.99 + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.0b7 + 6.0a1 + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.99.xpi + + + +
  • -- cgit From 4fea7aeaf6dc6f3687662882782658ed4b31e7e3 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Wed, 4 May 2011 17:50:28 +0200 Subject: Make filterByRegexp more tolerant to different configurations. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * filterByRegexp shouldn’t crash when list is undefined * also be more tolerant for nonexistent some RH-specific functions Fixes #91. --- data/lib/otherButtons.js | 4 ++-- data/lib/util.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js index 0e7b408..a766668 100644 --- a/data/lib/otherButtons.js +++ b/data/lib/otherButtons.js @@ -60,10 +60,10 @@ function markBugTriaged() { // /fedora-meeting.2009-11-24-15.11.log.html // http://meetbot.fedoraproject.org/fedora-meeting/2009-11-24\ // /fedora-meeting.2009-11-24-15.11.log.html - if (!hasXorgBugsCategory()) { + if (hasXorgBugsCategory && !hasXorgBugsCategory()) { alert("This won't do! First set the category!"); } - else if (!isEnterprise() && (getSeverity() == 'unspecified')) { + else if (isEnterprise && !isEnterprise() && (getSeverity() == 'unspecified')) { alert("This won't do! Specify some severity!"); } else { diff --git a/data/lib/util.js b/data/lib/util.js index 064887c..dc927b6 100644 --- a/data/lib/util.js +++ b/data/lib/util.js @@ -294,7 +294,7 @@ function removeCSVValue(str, value) { */ function filterByRegexp(list, chosingMark) { var chosenPair = []; - if (list.length > 0) { + if (list && list.length > 0) { chosenPair = list.filter(function (pair) { return new RegExp(pair.regexp, "i").test(chosingMark); }); -- cgit From 45213cd6b0810fd74eede4c06fae768350f10e9f Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Wed, 4 May 2011 17:54:41 +0200 Subject: Our 0.100 revisioin. Let’s see whether it breaks Add-on SDK. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- update.rdf | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5abbd52..03324dc 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "description": "Additional buttons and other function helping in the triage on bugzilla", "author": "Matej Cepl (http://matej.ceplovi.cz)", "license": "MIT/X11 (http://opensource.org/licenses/mit-license.php) and MPL", - "version": "0.99", + "version": "0.100", "contributors": [ "Ehsan Akhgari (http://ehsanakhgari.org/) ", "Johnathan Nightingale (http://johnath.com) ", diff --git a/update.rdf b/update.rdf index 1499e88..f47e944 100644 --- a/update.rdf +++ b/update.rdf @@ -382,6 +382,21 @@ xmlns:em="http://www.mozilla.org/2004/em-rdf#"> +
  • + + 0.100 + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.0b7 + 6.0a1 + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.100.xpi + + + +
  • -- cgit From c603f0a1a2985bf225786122beeaf248ca87cd99 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 5 May 2011 12:02:51 +0200 Subject: Make the script more reliable against JSON-hosting sites being down. Fixes #92 --- data/lib/otherButtons.js | 8 ++++---- lib/libbugzilla.js | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js index a766668..6bcc043 100644 --- a/data/lib/otherButtons.js +++ b/data/lib/otherButtons.js @@ -113,9 +113,9 @@ function addingEmbelishments(list) { } // TODO Get compiz bugs as well - if ((constantData.chipNames) && (list[0]) + if ((new Boolean(constantData.chipNames)) && (list[0].length > 0) && (!FillMagicDoneRE.test(getSummary())) - && (maintCCAddr === "xgl-maint@redhat.com")) { + && (maintCCAddr == "xgl-maint@redhat.com")) { // Add find chip magic button var whiteboard_string = document .getElementById("status_whiteboard").value; @@ -197,8 +197,8 @@ function setBranding(xLogAtts) { var compElems; if (config.suspiciousComponents && isInList(getComponent(), config.suspiciousComponents) - && (compElems = document - .getElementById("bz_component_edit_container"))) { + && ((compElems = document + .getElementById("bz_component_edit_container")))) { compElems.style.background = "red none"; } diff --git a/lib/libbugzilla.js b/lib/libbugzilla.js index a1792ea..3763eff 100644 --- a/lib/libbugzilla.js +++ b/lib/libbugzilla.js @@ -379,6 +379,8 @@ exports.initialize = function initialize(config, callback) { onComplete: function(response) { if (response.status == 200) { config.constantData[title] = response.json; + } else { + console.error("Cannot download " + title + " from URL " + url); } } }).get(); -- cgit From da49b6460ae02a1a1f0e86aef8f541798730a18f Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 5 May 2011 12:27:10 +0200 Subject: Make my console.myDebug configurable via about:config preference. That is the Boolean variable bugzilla-triage.setting.debug --- data/lib/bzpage.js | 4 ++-- data/lib/util.js | 9 ++++----- data/rhlib/rhbzpage.js | 3 +-- lib/libbugzilla.js | 24 +++++++++++++++++------- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/data/lib/bzpage.js b/data/lib/bzpage.js index d957bd3..296fe29 100644 --- a/data/lib/bzpage.js +++ b/data/lib/bzpage.js @@ -22,7 +22,7 @@ var equivalentComponents = null; * central handler processing messages from the main script. */ self.on('message', function onMessage(msg) { - console.log("onMessage - incoming : msg.cmd = " + msg.cmd); + console.myDebug("onMessage - incoming : msg.cmd = " + msg.cmd); switch (msg.cmd) { case "ReloadThePage": document.location.reload(true); @@ -80,7 +80,7 @@ function executeCommand(cmdObj) { * Object with the appropriate parameters for the command */ function centralCommandDispatch (cmdLabel, cmdParams) { - console.log("centralCommandDispatch : cmdLabel = " + cmdLabel); + console.myDebug("centralCommandDispatch : cmdLabel = " + cmdLabel); switch (cmdLabel) { case "name": case "position": diff --git a/data/lib/util.js b/data/lib/util.js index dc927b6..11cf3bc 100644 --- a/data/lib/util.js +++ b/data/lib/util.js @@ -375,11 +375,10 @@ NotLoggedinException.prototype.toString = function () { return this.name + ': "' + this.message + '"'; }; -// Are we debugging? -var debugFlag = true; - console.myDebug = function myDebug(str) { - if (debugFlag) { - console.log(str); + if (typeof config !== "undefined") { + if (config.debuggingVerbose) { + console.log(str); + } } }; diff --git a/data/rhlib/rhbzpage.js b/data/rhlib/rhbzpage.js index 752e471..55314d5 100644 --- a/data/rhlib/rhbzpage.js +++ b/data/rhlib/rhbzpage.js @@ -131,7 +131,6 @@ function RHcentralCommandDispatch(cmdLabel, cmdParams) { markBugTriaged(); break; case "chipMagic": - console.myDebug("cmdParams = " + cmdParams.toSource()); fillInWhiteBoard(cmdParams); break; // If we don't have it here, call superclass method @@ -254,7 +253,6 @@ function fillInChipMagic(XlogID) { function chipsetMagic (interestingLineArr) { // parse Xorg.0.log var cardStr = ""; - console.myDebug("interestingLineArr = " + interestingLineArr.toSource()); console.myDebug("interestingLineArr[1] = " + interestingLineArr[1]); if (interestingLineArr.length >0) { @@ -499,6 +497,7 @@ function RHBZinit() { // Xorg.0.log must be text, otherwise we cannot parse it return (/[xX].*log/.test(value[0]) && /text/.test(value[2])); }); + // Just add a link to every Xorg.0.log link analyzing it. addCheckXorgLogLink(XorgLogAttList); diff --git a/lib/libbugzilla.js b/lib/libbugzilla.js index 3763eff..990c759 100644 --- a/lib/libbugzilla.js +++ b/lib/libbugzilla.js @@ -329,13 +329,13 @@ exports.makeJSONRPCCall = function makeJSONRPCCall(url, method, params, callback "params": params }; - console.myDebug("makeJSONRPCCall: out = " + JSON.stringify(msg)); +// console.log("makeJSONRPCCall: out = " + JSON.stringify(msg)); Request({ url: url, onComplete: function(response) { if (response.status == 200) { - console.myDebug("makeJSONRPCCall: in = " + response.text); +// console.log("makeJSONRPCCall: in = " + response.text); callback(response.json.result); } }, @@ -345,15 +345,24 @@ exports.makeJSONRPCCall = function makeJSONRPCCall(url, method, params, callback }; exports.initialize = function initialize(config, callback) { - var prefName = BTSPrefNS+"JSONURL"; - var urlStr = ""; + var prefJSONURLName = BTSPrefNS+"JSONURL"; + var prefDebugName = BTSPrefNS+"debug"; + var urlStr = "", + debugOption = false; // should we spit out a lot of debugging output - if (preferences.isSet(prefName)) { - urlStr = preferences.get(prefName); + if (preferences.isSet(prefJSONURLName)) { + urlStr = preferences.get(prefJSONURLName); } else { urlStr = JSONURLDefault; - preferences.set(prefName, JSONURLDefault); + preferences.set(prefJSONURLName, JSONURLDefault); + } + + if (preferences.isSet(prefDebugName)) { + debugOption = preferences.get(prefDebugName); + } + else { + preferences.set(prefDebugName, debugOption); } // Randomize URL to avoid caching @@ -388,6 +397,7 @@ exports.initialize = function initialize(config, callback) { } config.configData = {}; + config.configData.debuggingVerbose = debugOption; config.configData.matches = config.gJSONData.configData.matches; config.configData.skipMatches = config.configData.matches.map(function(x) { return x.replace("show_bug.cgi.*","((process|post)_bug|attachment)\.cgi$"); -- cgit From 49feb276224dfa812339b94cfe52ea8f0ee5c491 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 5 May 2011 18:41:00 +0200 Subject: Add makeJSONRPCCallWithLogin, and other small issues. * Release 0.102 * Don't react on bugzilla.gnome.org per default * Simplify handling of preferences and debugging output. --- data/lib/otherButtons.js | 2 +- data/rhlib/fixingAttMIME.js | 1 + jsons/Config_data.json | 3 +- lib/libbugzilla.js | 67 ++++++++++++++++++++++++++++----------------- lib/main.js | 24 ++++++++++++---- package.json | 2 +- update.rdf | 30 ++++++++++++++++++++ 7 files changed, 94 insertions(+), 35 deletions(-) diff --git a/data/lib/otherButtons.js b/data/lib/otherButtons.js index 6bcc043..6fa48e0 100644 --- a/data/lib/otherButtons.js +++ b/data/lib/otherButtons.js @@ -113,7 +113,7 @@ function addingEmbelishments(list) { } // TODO Get compiz bugs as well - if ((new Boolean(constantData.chipNames)) && (list[0].length > 0) + if ((new Boolean(constantData.chipNames)) && (list.length > 0) && (!FillMagicDoneRE.test(getSummary())) && (maintCCAddr == "xgl-maint@redhat.com")) { // Add find chip magic button diff --git a/data/rhlib/fixingAttMIME.js b/data/rhlib/fixingAttMIME.js index c2adde4..ada6974 100644 --- a/data/rhlib/fixingAttMIME.js +++ b/data/rhlib/fixingAttMIME.js @@ -64,6 +64,7 @@ function fixAttachById(id, XMLRPCURL, type, email) { self.postMessage(new Message("MakeJSONRPCall", { url : XMLRPCURL.replace("xmlrpc.cgi","jsonrpc.cgi"), method : "bugzilla.updateAttachMimeType", + login: getLogin(), params : params, callRPC : "FixAttachmentMIMECallback" })); diff --git a/jsons/Config_data.json b/jsons/Config_data.json index 8db7b27..8f2f6e2 100644 --- a/jsons/Config_data.json +++ b/jsons/Config_data.json @@ -112,8 +112,7 @@ "objectStyle":"RH", "matches":[ "https://bugzilla.redhat.com/show_bug.cgi.*", - "https://bugzilla.mozilla.org/show_bug.cgi.*", - "https://bugzilla.gnome.org/show_bug.cgi.*" + "https://bugzilla.mozilla.org/show_bug.cgi.*" ], "enabledPackages":{ "bugzilla.redhat.com":"all" diff --git a/lib/libbugzilla.js b/lib/libbugzilla.js index 990c759..ae4ea01 100644 --- a/lib/libbugzilla.js +++ b/lib/libbugzilla.js @@ -26,6 +26,7 @@ var copiedAttributes = [ "queryButton", "upstreamButton", "parseAbrtBacktraces", var passwords = {}; // hash of passwords indexed by a hostname var config = exports.config = {}; +var debugOption = false; function Message(cmd, data) { console.log("Message: cmd = " + cmd + ", data = " + data); @@ -37,6 +38,12 @@ function log(msg) { postMessage(new Message("LogMessage", msg)); } +function debug(str) { + if (debugOption) { + console.log(str); + } +} + /** * parse XML object out of string working around various bugs in Gecko * implementation see https://developer.mozilla.org/en/E4X for more information @@ -61,7 +68,7 @@ function parseXMLfromString (inStuff) { * This is a slow variant for bugs other than actual window */ function getRealBugNoSlow(bugNo, location, callback) { - console.log("We have to deal with bug aliased as " + this.bugNo); + debug("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", @@ -73,7 +80,7 @@ function getRealBugNoSlow(bugNo, location, callback) { if (isNaN(bugID)) { throw new Error("Cannot get bug no. even from XML representation!"); } - console.log("The real bug no. is " + bugID); + debug("The real bug no. is " + bugID); callback(bugID) } } @@ -133,7 +140,7 @@ function getPassword(login, domain, callback) { exports.changeJSONURL = function changeJSONURL() { var prfNm = BTSPrefNS+"JSONURL"; - var url = preferences.get(prfNm,""); + var url = preferences.get(prfNm, JSONURLDefault); var reply = prompts.prompt("New location of JSON configuration file", url); if (reply && (reply != url)) { @@ -287,7 +294,7 @@ exports.createUpstreamBug = function createUpstreamBug(urlStr, subject, comment) exports.makeXMLRPCCall = function makeXMLRPCCall(url, login, method, params, callback) { var urlObj = urlMod.URL(url); getPassword(login, - urlObj.schema + "://" + urlObj.host, + urlObj.scheme + "://" + urlObj.host, function (passwObj) { if (!passwObj.password) { // TODO this should happen, only when user presses Escape in password @@ -317,25 +324,46 @@ exports.makeXMLRPCCall = function makeXMLRPCCall(url, login, method, params, cal ); }; +exports.makeJSONRPCCallWithLogin = function makeJSONRPCCallWithLogin(url, method, params, + login, callback) { + var urlObj = urlMod.URL(url); + getPassword(login, + urlObj.scheme + "://" + urlObj.host, + function (passObj) { + if (!passObj.password) { + return; + } + + makeJSONRPCCall(url, "User.login", { + login: login, + password: passObj.password, + remember: false + }, function(logResult) { + console.log("logResult = " + logResult.toSource()); + makeJSONRPCCall(url, method, params, callback); + }); + } + ); +}; + // Make a JSONL-RPC call ... most of the business logic should stay in the // content script // http://json-rpc.org/wd/JSON-RPC-1-1-WD-20060807.html -exports.makeJSONRPCCall = function makeJSONRPCCall(url, method, params, callback) { +var makeJSONRPCCall = exports.makeJSONRPCCall = function makeJSONRPCCall(url, method, params, callback) { -// {"version":"1.1", "method":"Bug.history", "params":{ "ids":[12345] } } var msg = { "version": "1.1", "method": method, "params": params }; -// console.log("makeJSONRPCCall: out = " + JSON.stringify(msg)); + debug("makeJSONRPCCall: out = " + JSON.stringify(msg)); Request({ url: url, onComplete: function(response) { if (response.status == 200) { -// console.log("makeJSONRPCCall: in = " + response.text); + debug("makeJSONRPCCall: in = " + response.text); callback(response.json.result); } }, @@ -346,24 +374,13 @@ exports.makeJSONRPCCall = function makeJSONRPCCall(url, method, params, callback exports.initialize = function initialize(config, callback) { var prefJSONURLName = BTSPrefNS+"JSONURL"; - var prefDebugName = BTSPrefNS+"debug"; - var urlStr = "", - debugOption = false; // should we spit out a lot of debugging output + var urlStr = preferences.get(prefJSONURLName, JSONURLDefault); + preferences.set(prefJSONURLName, urlStr); - if (preferences.isSet(prefJSONURLName)) { - urlStr = preferences.get(prefJSONURLName); - } - else { - urlStr = JSONURLDefault; - preferences.set(prefJSONURLName, JSONURLDefault); - } - - if (preferences.isSet(prefDebugName)) { - debugOption = preferences.get(prefDebugName); - } - else { - preferences.set(prefDebugName, debugOption); - } + // should we spit out a lot of debugging output + var prefDebugName = BTSPrefNS+"debug"; + debugOption = preferences.get(prefDebugName, false); + preferences.set(prefDebugName, debugOption); // Randomize URL to avoid caching // TODO see https://fedorahosted.org/bugzilla-triage-scripts/ticket/21 diff --git a/lib/main.js b/lib/main.js index 302dda8..431ffe6 100644 --- a/lib/main.js +++ b/lib/main.js @@ -101,12 +101,24 @@ var messageHandler = exports.messageHandler = function messageHandler( break; case "MakeJSONRPCall": // url, login, method, params, callback - libbz - .makeJSONRPCCall(msg.data.url, msg.data.method, - msg.data.params, function(ret) { - worker.postMessage(new Message(msg.data.callRPC, - ret)); - }); + if (msg.data.login) { + libbz + .makeJSONRPCCallWithLogin(msg.data.url, msg.data.method, + msg.data.params, msg.data.login, function(ret) { + worker.postMessage(new Message(msg.data.callRPC, + ret)); + } + ); + } + else { + libbz + .makeJSONRPCCall(msg.data.url, msg.data.method, + msg.data.params, function(ret) { + worker.postMessage(new Message(msg.data.callRPC, + ret)); + } + ); + } break; case "GetURL": libbz.getURL(msg.data.url, diff --git a/package.json b/package.json index 03324dc..c13962a 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "description": "Additional buttons and other function helping in the triage on bugzilla", "author": "Matej Cepl (http://matej.ceplovi.cz)", "license": "MIT/X11 (http://opensource.org/licenses/mit-license.php) and MPL", - "version": "0.100", + "version": "0.102", "contributors": [ "Ehsan Akhgari (http://ehsanakhgari.org/) ", "Johnathan Nightingale (http://johnath.com) ", diff --git a/update.rdf b/update.rdf index f47e944..6aa724b 100644 --- a/update.rdf +++ b/update.rdf @@ -397,6 +397,36 @@ xmlns:em="http://www.mozilla.org/2004/em-rdf#"> +
  • + + 0.101 + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.0b7 + 6.0a1 + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.101.xpi + + + +
  • +
  • + + 0.102 + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 4.0b7 + 6.0a1 + + https://fedorahosted.org/released/bugzilla-triage-scripts/bugzilla-triage-0.102.xpi + + + +
  • -- cgit From da71521fe0a926a82c682d02688895c41d9d22fb Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Fri, 6 May 2011 19:46:42 +0200 Subject: Removing unimportant parts of the page as a prevention against #65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is now complete analysis of the issue, but I don’t know how to fix it, because we just write into various input boxes and they got focus (and subsequently Firefox makes them visible). --- data/lib/bugzillaDOMFunctions.js | 86 ++++++++++------ data/lib/bzpage.js | 2 + jsons/Config_data.json | 216 +++++++++++++++++++++------------------ 3 files changed, 173 insertions(+), 131 deletions(-) diff --git a/data/lib/bugzillaDOMFunctions.js b/data/lib/bugzillaDOMFunctions.js index f58f0d9..4437e7c 100644 --- a/data/lib/bugzillaDOMFunctions.js +++ b/data/lib/bugzillaDOMFunctions.js @@ -4,13 +4,13 @@ /** * Select option with given value on the