Browse files

added initial files

  • Loading branch information...
0 parents commit 64c22b60031d147da471d9ef7fe395be3ee3f5c6 @harthur committed Feb 10, 2010
7 chrome.manifest
@@ -0,0 +1,7 @@
+content bugid chrome/content/
+locale bugid en-US chrome/locale/en-US/
+skin bugid classic/1.0 chrome/skin/
+ overlay chrome://browser/content/browser.xul chrome://bugid/content/firefoxOverlay.xul
+overlay chrome://messenger/content/messenger.xul chrome://bugid/content/tbirdOverlay.xul
+overlay chrome://messenger/content/messageWindow.xul chrome://bugid/content/tbirdOverlay.xul
+
300 chrome/content/bugzillaRPC.js
@@ -0,0 +1,300 @@
+/* ***** 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 API Test Interface
+ *
+ * The Initial Developer of the Original Code is
+ * Heather Arthur.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 bugzillaRPC = {
+ setUrl : function(url) {
+ xmlRpc.setUrl(url);
+ },
+
+ getBug : function(id, callback, errback) {
+ xmlRpc.methodCall("Bug.get_bugs", [{ids: [id]}],
+ function(resp) {callback(resp.bugs[0]);}, errback);
+ },
+
+ getBugs : function(ids, callback, errback) {
+ xmlRpc.methodCall("Bug.get_bugs", [{ids: ids}],
+ function(resp) {callback(resp.bugs);}, errback);
+ },
+
+ advancedSearch : function(params, callback, errback) {
+ var feedCallback = function(xml){
+ var bugs = [];
+ var entries = xml.getElementsByTagName("entry");
+ for(var i = 0; i < entries.length; i++) {
+ var title = entries[i].getElementsByTagName("title")[0].firstChild.data;
+ var matches = /\Bug (\d*)/.exec(title);
+ bugs[i] = matches[1];
+ }
+ bugzillaRPC.getBugs(bugs, callback, errback);
+ };
+ params['ctype'] = 'atom';
+ var url = xmlRpc.url + "buglist.cgi?" + bugXhr.urlParams(params);
+ bugXhr.xhrGET(url, feedCallback , errback);
+ },
+
+ /* fastAdvancedSearch is faster because it only makes one xhr call, but the
+ id and summary are the only pieces of information retreived for each bug */
+ fastAdvancedSearch : function(params, callback, errback) {
+ var feedCallback = function(xml){
+ var bugs = [];
+ var entries = xml.getElementsByTagName("entry");
+ for(var i = 0; i < entries.length; i++) {
+ var title = entries[i].getElementsByTagName("title")[0].firstChild.data;
+ var matches = /\[Bug (\d*)\](.*)/.exec(title);
+ bugs[i] = {id: matches[1], summary : matches[2]};
+ }
+ callback(bugs);
+ };
+ params['ctype'] = 'atom';
+ var url = xmlRpc.url + "buglist.cgi?" + bugXhr.urlParams(params);
+ bugXhr.xhrGET(url, feedCallback , errback);
+ },
+
+ login : function(username, password, callback, errback, remember) {
+ xmlRpc.methodCall("User.login",
+ [{login: username, password: password, remember: remember}],
+ function(resp) {callback(resp.id);} , errback);
+ },
+
+ logout : function(callback, errback) {
+ xmlRpc.methodCall("User.logout", [], callback, errback);
+ },
+
+ createBug : function(bugInfo, callback, errback) {
+ xmlRpc.methodCall("Bug.create", [bugInfo],
+ function(resp) {callback(resp.id);}, errback);
+ },
+
+ offerAccount : function(email, callback, errback) {
+ xmlRpc.methodCall("User.offer_account_by_email",
+ [{email: email}],
+ function(resp) {callback(resp.id);}, errback);
+ },
+
+ legalValues : function(field, product, callback, errback) {
+ xmlRpc.methodCall("Bug.legal_values",
+ [{field: field, product: product}],
+ function(resp) {callback(resp.values);}, errback);
+ }
+};
+
+
+var xmlRpc = {
+ url : "https://bugzilla.mozilla.org/",
+
+ setUrl : function(url) {
+ xmlRpc.url = url;
+ },
+
+ methodCall : function(methodName, params, callback, errback) {
+ var newCallback =
+ function(response) {
+ var resp = xmlRpc.getResponse(response);
+ if(resp.faultString)
+ errback(resp.faultString);
+ else
+ callback(resp);
+ };
+ var callText = xmlRpc.buildCall(methodName, params);
+ bugXhr.xhrPOST(xmlRpc.url + "xmlrpc.cgi", callText, newCallback, errback);
+ },
+
+ buildCall : function(methodName, params) {
+ var method = '<?xml version="1.0"?>';
+ method += "<methodCall>";
+ method += "<methodName>" + methodName + "</methodName><params>";
+ for(var i = 0; i < params.length; i++)
+ method += "<param>" + xmlRpc.buildValue(params[i]) + "</param>";
+ method += "</params></methodCall>";
+ return method;
+ },
+
+ buildStruct : function(members) {
+ var struct = "<struct>";
+ for(key in members) {
+ struct += "<member><name>" + key + "</name>"
+ + xmlRpc.buildValue(members[key]) + "</member>";
+ }
+ struct += "</struct>";
+ return struct;
+ },
+
+ buildArray : function(values) {
+ var array = "<array><data>";
+ for(var i = 0; i < values.length; i++)
+ array += xmlRpc.buildValue(values[i]);
+ array += "</data></array>";
+ return array;
+ },
+
+ buildValue : function(val) {
+ var value = "<value>";
+ switch(typeof(val)) {
+ case 'number':
+ value += "<int>" + val + "</int>";
+ break;
+ case 'string':
+ value += "<string>" + val + "</string>";
+ break;
+ case 'boolean':
+ value += "<boolean>" + val + "</boolean>";
+ break;
+ case 'object':
+ if(val instanceof Array)
+ value += xmlRpc.buildArray(val);
+ else
+ value += xmlRpc.buildStruct(val);
+ break;
+ default:
+ break;
+ }
+ value += "</value>";
+ return value;
+ },
+
+ getResponse : function(xml) {
+ var fault = xml.firstChild.firstChild;
+ if(fault.nodeName == 'fault')
+ return xmlRpc.getStruct(fault.firstChild.firstChild);
+ var type = xml.firstChild.firstChild.firstChild.firstChild.firstChild;
+ if(type == null)
+ return {};
+ switch(type.nodeName) {
+ case "struct":
+ return xmlRpc.getStruct(type);
+ case "array":
+ return xmlRpc.getArray(type);
+ case "value":
+ return xmlRpc.getValue(type);
+ default:
+ return xmlRpc.getValue(type);
+ };
+ },
+
+ getStruct : function(struct) {
+ var members = struct.childNodes;
+ var retval = {};
+ for(var i = 0; i < members.length; i++) {
+ var member = members[i];
+ var key = member.firstChild.firstChild.data;
+ var value = xmlRpc.getValue(member.childNodes[1]);
+ retval[key] = value;
+ }
+ return retval;
+ },
+
+ getArray : function(array) {
+ var values = array.firstChild.childNodes;
+ var retval = [];
+ for(var i = 0; i < values.length; i++)
+ retval.push(xmlRpc.getValue(values[i]));
+ return retval;
+ },
+
+ getValue : function(value) {
+ if(!value.firstChild)
+ return '';
+ if(!value.firstChild.firstChild)
+ return '';
+ var data = value.firstChild.firstChild.data;
+ switch(value.firstChild.nodeName) {
+ case 'i2': case 'int':
+ return parseInt(data);
+ case 'boolean':
+ return parseInt(data) == 1 ? true : false;
+ case 'string':
+ return data;
+ case 'double':
+ return parseFloat(data);
+ case 'dateTime':
+ return Date(data);
+ case 'array':
+ return xmlRpc.getArray(value.firstChild);
+ case 'struct':
+ return xmlRpc.getStruct(value.firstChild);
+ default:
+ return data;
+ }
+ }
+};
+
+var bugXhr = {
+ xhrPOST : function (url, data, callback, errback) {
+ var req = new XMLHttpRequest();
+ req.open("POST", url, true);
+ req.setRequestHeader("Content-type", "text/xml");
+ req.setRequestHeader("Content-length", data.length);
+ req.setRequestHeader("Connection", "close");
+ req.onreadystatechange = function (event) {
+ if (req.readyState == 4) {
+ if(req.status == 200 && callback) {
+ callback(req.responseXML);
+ }
+ else if(errback)
+ errback("Connection error: HTTP code " + req.status);
+ }
+ };
+ req.send(data);
+ },
+
+ xhrGET : function(url, callback, errback) {
+ var req = new XMLHttpRequest();
+ req.open('GET', url, true);
+ req.onreadystatechange = function (event) {
+ if (req.readyState == 4) {
+ if(req.status == 200 && callback) {
+ callback(req.responseXML);
+ }
+ else if(errback)
+ errback("Connection error: HTTP code " + req.status);
+ }
+ };
+ req.send(null);
+ },
+
+ urlParams : function(params) {
+ var url = [];
+ for(var param in params)
+ url.push(param + "=" + params[param]);
+ return url.join("&");
+ },
+
+ urlEncode : function(params) {
+ var url = [];
+ for(var param in params)
+ url.push(encodeURIComponent(param) + "=" + encodeURIComponent(params[param]));
+ return url.join("&");
+ }
+};
57 chrome/content/firefoxOverlay.xul
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ***** 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 Bug Id Helper.
+ -
+ - The Initial Developer of the Original Code is
+ - Heather Arthur.
+ - Portions created by the Initial Developer are Copyright (C) 2009
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - 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 ***** -->
+<!DOCTYPE overlay SYSTEM "chrome://bugid/locale/bugid.dtd">
+<overlay id="bugid-overlay"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="BugIdHelper.onload();">
+
+ <stringbundleset id="stringbundleset">
+ <stringbundle id="bugid-strings" src="chrome://bugid/locale/bugid.properties"/>
+ </stringbundleset>
+
+ <script type="application/x-javascript" src="chrome://bugid/content/overlay.js"/>
+ <script type="application/x-javascript" src="chrome://bugid/content/bugzillaRPC.js"/>
+
+ <popup id="contentAreaContextMenu">
+ <menuitem id="context-bugid"
+ insertafter="context-sep-selectall"
+ oncommand="bugIdHelper.openSelection()"
+ class="menuitem-iconic"
+ image="chrome://bugid/skin/bugzilla.png"
+ accesskey="&bugid.accesskey;"/>
+ </popup>
+</overlay>
165 chrome/content/options.js
@@ -0,0 +1,165 @@
+/* ***** 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 Bug ID Helper
+ *
+ * The Initial Developer of the Original Code is
+ * Heather Arthur.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 hostUrl = "chrome://bugid/content/options.xul";
+
+/* toggle disabled attribute of all children */
+function togglePrefs(className, toggleId) {
+ var disable = !document.getElementById(toggleId).checked;
+ var elems = xpathNodes(document,
+ './/*[contains(concat(" ",normalize-space(@class)," ")," ' + className + ' ")]');
+ for(var i = 0, len = elems.length; i < len; i++)
+ elems[i].disabled = disable;
+}
+
+function xpathNodes(doc, expression, element) {
+ var target = element || doc;
+ var results = [];
+ var query = doc.evaluate(expression, target,
+ null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ for (var i = 0, len = query.snapshotLength; i < len; i++)
+ results.push(query.snapshotItem(i));
+ return results;
+}
+
+function saveLogin() {
+ var username = document.getElementById("loginbox").value;
+ var password = document.getElementById("passbox").value;
+ var url = document.getElementById("urlbox").value;
+ var oldLogin = getLogin();
+
+ if(!username || !password) {
+ // if they remove their username/password, delete they're login
+ if ("@mozilla.org/passwordmanager;1" in Components.classes) {
+ // Thunderbird 2
+ var passwordManager = Components.classes["@mozilla.org/passwordmanager;1"]
+ .getService(Components.interfaces.nsIPasswordManager);
+ if(oldLogin.username)
+ passwordManager.removeUser(hostUrl, oldLogin.username);
+ }
+ else if ("@mozilla.org/login-manager;1" in Components.classes) {
+ // Thunderbird 3, Firefox 3
+ var loginManager = Components.classes["@mozilla.org/login-manager;1"]
+ .getService(Components.interfaces.nsILoginManager);
+ var nsLoginInfo = new Components.Constructor(
+ "@mozilla.org/login-manager/loginInfo;1",
+ Components.interfaces.nsILoginInfo,
+ "init");
+ var logins = loginManager.findLogins({}, hostUrl, "", null);
+
+ if(logins.length > 0) {
+ // they're changing their username or password
+ var oldLogin = new nsLoginInfo(hostUrl, "", null, logins[0].username,
+ logins[0].password, "loginbox", "passbox");
+ loginManager.removeLogin(logins[0]);
+ }
+ }
+ return;
+ }
+
+ if ("@mozilla.org/passwordmanager;1" in Components.classes) {
+ // Thunderbird 2
+ var passwordManager = Components.classes["@mozilla.org/passwordmanager;1"]
+ .getService(Components.interfaces.nsIPasswordManager);
+ if(oldLogin.username) {
+ passwordManager.removeUser(hostUrl, oldLogin.username); }
+ passwordManager.addUser(hostUrl, username, password);
+ }
+ else if ("@mozilla.org/login-manager;1" in Components.classes) {
+ // Thunderbird 3, Firefox 3
+ var loginManager = Components.classes["@mozilla.org/login-manager;1"]
+ .getService(Components.interfaces.nsILoginManager);
+ var nsLoginInfo = new Components.Constructor(
+ "@mozilla.org/login-manager/loginInfo;1",
+ Components.interfaces.nsILoginInfo,
+ "init");
+ var loginInfo = new nsLoginInfo(hostUrl, "", null, username,
+ password, "loginbox", "passbox");
+ var logins = loginManager.findLogins({}, hostUrl, "", null);
+
+ if(logins.length > 0) {
+ // they're changing their username or password
+ var oldLogin = new nsLoginInfo(hostUrl, "", null, logins[0].username,
+ logins[0].password, "loginbox", "passbox");
+ loginManager.modifyLogin(logins[0], loginInfo);
+ }
+ else
+ loginManager.addLogin(loginInfo);
+ }
+
+ bugzillaRPC.setUrl(toBugzillaDomain(url));
+ bugzillaRPC.login(username, password,
+ function(){ try{ alert('Successfully logged in');} catch(e){}},
+ function(errMsg){ try{alert("Could not log in: " + errMsg);} catch(e){}});
+}
+
+function fillLogin() {
+ var userField = document.getElementById("loginbox");
+ var passField = document.getElementById("passbox");
+ var login = getLogin();
+ userField.value = login.username;
+ passField.value = login.password;
+}
+
+function getLogin() {
+ if ("@mozilla.org/passwordmanager;1" in Components.classes) {
+ // Thunderbird 2
+ var passwordManager = Components.classes["@mozilla.org/passwordmanager;1"]
+ .getService(Components.interfaces.nsIPasswordManager);
+ var e = passwordManager.enumerator;
+ while (e.hasMoreElements()) {
+ var loginInfo = e.getNext().QueryInterface(Components.interfaces.nsIPassword);
+ if (loginInfo.host == hostUrl)
+ return {username:loginInfo.user, password: loginInfo.password};
+ }
+ }
+ else if ("@mozilla.org/login-manager;1" in Components.classes) {
+ // Thunderbird 3, Firefox 3
+ var loginManager = Components.classes["@mozilla.org/login-manager;1"]
+ .getService(Components.interfaces.nsILoginManager);
+
+ var logins = loginManager.findLogins({}, hostUrl, "", null);
+ if(logins.length > 0)
+ return logins[0];
+ }
+ return {username:'', password:''};
+}
+
+function toBugzillaDomain(fragment) {
+ var domExp = /^(?:https?:\/\/)?([\w\.\/]*?)\/?(?:show_bug\.cgi\?id=)?$/;
+ var matches = fragment.match(domExp);
+ if(matches)
+ return "https://" + matches[1] + "/";
+}
133 chrome/content/options.xul
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ***** 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 Bug ID Helper.
+ -
+ - The Initial Developer of the Original Code is
+ - Heath Arthur.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - 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 ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://bugid/skin/bugidhelper.css"?>
+
+<!DOCTYPE prefwindow SYSTEM "chrome://bugid/locale/prefwindow.dtd">
+
+<prefwindow id="bugidPreferences" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="&prefwindow.title;"
+ persist="password">
+ <script type="application/x-javascript" src="chrome://bugid/content/options.js" />
+ <script type="application/x-javascript" src="chrome://bugid/content/bugzillaRPC.js" />
+ <prefpane id="pane1" label="preferences" onpaneload="fillLogin();">
+
+ <preferences>
+ <preference id="urlpref" name="extensions.bugid.url" type="string" />
+ <preference id="linkifypref" name="extensions.bugid.linkify" type="bool" />
+ <preference id="strikepref" name="extensions.bugid.link.strikethrough" type="bool" />
+ <preference id="resospref" name="extensions.bugid.link.strike.resos" type="string" />
+ <preference id="divertpref" name="extensions.bugid.link.diverted" type="bool" />
+ <preference id="tooltippref" name="extensions.bugid.tooltipify" type="bool" />
+ <preference id="toolidpref" name="extensions.bugid.tooltip.showid" type="bool" />
+ <preference id="toolstatpref" name="extensions.bugid.tooltip.showstat" type="bool" />
+ <preference id="tooldescpref" name="extensions.bugid.tooltip.showdesc" type="bool" />
+ <preference id="tooldatepref" name="extensions.bugid.tooltip.showdate" type="bool" />
+ <preference id="toolcomppref" name="extensions.bugid.tooltip.showcomp" type="bool" />
+ <preference id="toolassignpref" name="extensions.bugid.tooltip.showassign" type="bool"/>
+ <preference id="toolcommpref" name="extensions.bugid.tooltip.showcommenter" type="bool"/>
+ <preference id="toolerrorpref" name="extensions.bugid.tooltip.showerror" type="bool"/>
+ <preference id="filterpref" name="extensions.bugid.filter" type="bool" />
+ <preference id="whitelistpref" name="extensions.bugid.whitelist" type="string" />
+ </preferences>
+
+ <vbox class="category-prime">
+ <label control="textstringpref">&urlpref.label;</label>
+ <textbox id="urlbox" preference="urlpref"/>
+ </vbox>
+ <grid class="category" tooltiptext="&loginpref.tooltip;">
+ <columns>
+ <column/>
+ <column/>
+ </columns>
+ <rows>
+ <row>
+ <label control="textstringpref">&loginpref.label;</label>
+ <textbox id="loginbox" onchange="saveLogin();"/>
+ </row>
+ <row>
+ <label control="textstringpref">&passpref.label;</label>
+ <textbox id="passbox" type="password" onchange="saveLogin();"/>
+ </row>
+ </rows>
+ </grid>
+
+ <vbox class="category">
+ <checkbox id="linkboolpref" preference="linkifypref" label="&linkifypref.label;"
+ onsynctopreference="togglePrefs('linksubpref', 'linkboolpref')"
+ onsyncfrompreference="togglePrefs('linksubpref', 'linkboolpref')"/>
+ <vbox class="subpref">
+ <checkbox id="divertedbox" class="linksubpref" preference="divertpref" label="&divertpref.label;" />
+ <checkbox id="strikebox" class="linksubpref" preference="strikepref" label="&strikepref.label;"
+ onsynctopreference="togglePrefs('strikesubpref', 'strikebox')"
+ onsyncfrompreference="togglePrefs('strikesubpref', 'strikebox')"/>
+ <vbox class="subpref">
+ <textbox id="resosbox" class="strikesubpref" preference="resospref" />
+ </vbox>
+ </vbox>
+ </vbox>
+
+ <vbox class="category">
+ <checkbox id="toolboolpref" preference="tooltippref" label="&tooltippref.label;"
+ onsynctopreference="togglePrefs('toolsubprefs', 'toolboolpref')"
+ onsyncfrompreference="togglePrefs('toolsubprefs', 'toolboolpref')"/>
+ <vbox class="subpref">
+ <checkbox id="idbox" class="toolsubpref" preference="toolidpref" label="&toolidpref.label;" />
+ <checkbox id="statbox" class="toolsubpref" preference="toolstatpref" label="&toolstatpref.label;" />
+ <checkbox id="datebox" class="toolsubpref" preference="tooldatepref" label="&tooldatepref.label;" />
+ <checkbox id="assignbox" class="toolsubpref" preference="toolassignpref" label="&toolassignpref.label;" />
+ <checkbox id="compbox" class="toolsubpref" preference="toolcomppref" label="&toolcomppref.label;" />
+ <checkbox id="descbox" class="toolsubpref" preference="tooldescpref" label="&tooldescpref.label;" />
+ <checkbox id="commbox" class="toolsubpref" preference="toolcommpref" label="&toolcommpref.label;"
+ tooltiptext="&toolcommpref.tooltip;"/>
+ <checkbox id="errorbox" class="toolsubpref" preference="toolerrorpref" label="&toolerrorpref.label;"
+ tooltiptext="&toolerrorpref.tooltip;" />
+ </vbox>
+ </vbox>
+
+ <vbox class="category">
+ <checkbox id="filtboolpref" preference="filterpref" label="&filterpref.label;" control="whitelisttext"
+ onsyncfrompreference="togglePrefs('filtersubpref', 'filtboolpref')"
+ onsynctopreference="togglePrefs('filtersubpref', 'filtboolpref')" />
+ <vbox class="subpref">
+ <textbox id="whitelisttext" class="filtersubpref" preference="whitelistpref"/>
+ </vbox>
+ </vbox>
+
+ </prefpane>
+</prefwindow>
502 chrome/content/overlay.js
@@ -0,0 +1,502 @@
+/* ***** 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 Bug Id Helper
+ *
+ * The Initial Developer of the Original Code is
+ * Heather Arthur.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 ***** */
+window.addEventListener("load", function(){ bugIdHelper.init(); }, false);
+
+var bugIdHelper = {
+
+ /* 1 - bug id */
+ contextExp : /^(?:.*bug|ug|g)?\s*#?(\d{2,7})(?:$|\b)/i,
+
+ /* 1 - character before, 2 - text to linkify, 3 - bug id */
+ bugExp : /([^a-zA-Z]|^)(bugs?\s*(?:id)?\s*[#\:\-_]?\s*(\d+))/i,
+
+ /* 1 - base url */
+ baseUrlExp : /^(?:https?:\/\/)?([\w\:\.\/]*?)\/?(?:show_bug\.cgi\?id=)?$/,
+
+ /* 1 - domain */
+ domainExp : /^(?:https?:\/\/)?([\w\.\:\-~\/]*)\//,
+
+ /* 1 - url w/o protocol, 2 - base url, 3 - bug id, 4 - (optional) comment number */
+ urlExp : /(?:https?:\/\/)?(([\w\.\:\-\/]*\/?show_bug\.cgi\?)id=(\d+)(?:#c(\d+))?)/,
+
+ dateExp : /\d+\-\d+\-\d+/,
+
+ hostUrl : 'chrome://bugid/content/options.xul', // for login manager
+
+ init : function () {
+ this.strings = document.getElementById("bugid-strings");
+
+ this.prefService = Components.classes['@mozilla.org/preferences-service;1']
+ .getService(Components.interfaces.nsIPrefBranch2);
+
+ this.userUrl = this.prefService.getCharPref("extensions.bugid.url");
+ this.baseUrl = this.toBaseUrl(this.userUrl);
+ this.prefService.addObserver("extensions.bugid.url", this, false);
+
+ var urls = this.prefService.getCharPref("extensions.bugid.whitelist");
+ this.domainExps = this.toDomains(urls);
+ this.prefService.addObserver("extensions.bugid.whitelist", this, false);
+
+ var resos = this.prefService.getCharPref("extensions.bugid.link.strike.resos");
+ this.strikeResos = resos.split(/[\.,\s]+/);
+ this.prefService.addObserver("extensions.bugid.link.strike.resos", this, false);
+
+ /* add context menu popup listener */
+ var contextmenu = document.getElementById("contentAreaContextMenu");
+ if(contextmenu)
+ contextmenu.addEventListener("popupshowing", function(){ bugIdHelper.contextShowing(); }, false);
+
+ /* add content page load listener */
+ var content = document.getElementById("appcontent");
+ if(content)
+ content.addEventListener("load", function(e) { bugIdHelper.contentLoad(e); }, true);
+
+ /* thunderbird email load */
+ var messagepane = document.getElementById("messagepane");
+ if(messagepane)
+ messagepane.addEventListener("load", function(e) { bugIdHelper.contentLoad(e); }, true);
+ },
+
+ observe : function(subject, topic, data) {
+ if (topic == "nsPref:changed") {
+ switch(data) {
+ case "extensions.bugid.url":
+ this.userUrl = this.prefService.getCharPref("extensions.bugid.url")
+ this.baseUrl = this.toBaseUrl(this.userUrl);
+ break;
+ case "extensions.bugid.whitelist":
+ var urls = this.prefService.getCharPref("extensions.bugid.whitelist");
+ this.domainExps = this.toDomains(urls);
+ break;
+ case "extensions.bugid.link.strike.resos":
+ var resos = this.prefService.getCharPref("extensions.bugid.link.strike.resos");
+ this.strikeResos = resos.split(/[\.,\s]+/);
+ break;
+ default:
+ break;
+ }
+ }
+ },
+
+ /*--- context menu ---*/
+ openSelection : function () {
+ var bugurl = this.baseUrl + "id=" + this.selectedBug;
+ var loadInBackground = this.prefService.getBoolPref("browser.tabs.loadDivertedInBackground");
+ gBrowser.loadOneTab(bugurl, null, null, null, loadInBackground, false);
+ },
+
+ contextShowing : function() {
+ var bugItem = document.getElementById("context-bugid");
+ var selection = getBrowserSelection();
+ var matches = selection.match(this.contextExp);
+
+ if(matches) {
+ this.selectedBug = matches[1];
+ bugItem.hidden = false;
+ bugItem.label = this.strings.getFormattedString("contextItem", [this.selectedBug]);
+ }
+ else
+ bugItem.hidden = true;
+ },
+
+ /*--- linkification ---*/
+ contentLoad : function(event) {
+ var doc = event.originalTarget;
+ if(this.canBugify(doc)) {
+ bugIdHelper.bugifyContent(doc, doc.body);
+ /* listen for node insertion (gmail, etc.) */
+ doc.addEventListener("DOMNodeInserted", function(e) {
+ if(e.target.className == "__firefox_bugidhelper")
+ return; // prevent possible infinite recursion
+ bugIdHelper.bugifyContent(doc, e.target);
+ }, true);
+ }
+ },
+
+ bugifyContent : function(doc, target) {
+ if(this.getBoolPref("linkify"))
+ this.linkifyContent(doc, target);
+ if(this.getBoolPref("tooltipify"))
+ this.tooltipifyContent(doc, target);
+ },
+
+ linkifyContent : function(doc, target) {
+ var textnodes = this.xpathNodes(doc,
+ "descendant::text()[contains(translate(., 'BUG', 'bug'),'bug')]", target);
+
+ for(var i = 0, len = textnodes.length; i < len; i++) {
+ var node = textnodes[i];
+ /* handle one match at a time so we can get index of regex */
+ while(node.data) {
+ var matches = this.bugExp.exec(node.data);
+ var urlmatches = this.urlExp.exec(node.data);
+
+ // we need to make sure we don't skip over plain text urls
+ if(matches && (!urlmatches || matches.index < urlmatches.index)) {
+ var index = matches.index;
+ var prelen = matches[1].length;
+ var bugtext = matches[2];
+ var url = this.baseUrl + "id=" + matches[3];
+ }
+ else if (urlmatches) {
+ var index = urlmatches.index;
+ var prelen = 0;
+ var bugtext = urlmatches[0];
+ var url = "http://" + urlmatches[1];
+ }
+ else
+ break;
+
+ /* snip out bug id */
+ var bug = node.splitText(index + prelen);
+ node = bug.splitText(bugtext.length);
+
+ var anchor = doc.createElement("a");
+ var text = doc.createTextNode(bugtext);
+ anchor.appendChild(text);
+ anchor.className = "__firefox_bugidhelper";
+
+
+ /* insert link */
+ node.parentNode.replaceChild(anchor, bug);
+
+ if(this.canSetHref(doc, anchor))
+ this.setLink(anchor, url);
+ }
+ }
+ },
+
+ setLink : function(element, url) {
+ element.setAttribute("href", url);
+ if(this.getBoolPref("link.diverted"))
+ element.setAttribute("target", "_blank");
+ },
+
+ /*--- tooltip ---*/
+ tooltipifyContent : function(doc, target) {
+ var links = this.xpathNodes(doc, 'descendant::a[contains(@href, "show_bug.cgi")]', target);
+ if(links.length > 0) {
+ var login = this.getLogin();
+ if(login.username) {
+ var userUrl = this.prefService.getCharPref("extensions.bugid.url");
+ bugzillaRPC.setUrl(this.toBugzillaDomain(userUrl));
+ bugzillaRPC.login(login.username, login.password,
+ function(){ bugIdHelper.tooltipifyLinks(doc, links);},
+ function(){ bugIdHelper.tooltipifyLinks(doc, links);});
+ }
+ else
+ this.tooltipifyLinks(doc, links);
+ }
+ else
+ this.tooltipifyLinks(doc, links);
+ },
+
+ tooltipifyLinks : function(doc, links) {
+ for(var i = 0; i < links.length; i++) {
+ var link = links[i];
+ var matches = bugIdHelper.urlExp.exec(link.getAttribute("href"));
+ if(matches) {
+ var base = matches[2];
+ if(base.length < 15) // on a bugzilla domain -override tooltip
+ base = bugIdHelper.domainExp.exec(doc.location.href)[1] + "/show_bug.cgi?";
+ var url = "http://" + base + "ctype=xml&excludefield=attachment&id=" + matches[3];
+ var commentId = matches[4];
+ if(commentId)
+ bugIdHelper.setComment(link, url, commentId);
+ else
+ bugIdHelper.setTooltip(link, url);
+ }
+ }
+ },
+
+ setTooltip : function(element, url) {
+ this.xhr(url,
+ function(wasSuccess, xml) {
+ if(!bugIdHelper) // this happens sometimes
+ return;
+ var showerror = bugIdHelper.getBoolPref("tooltip.showerror");
+ if(!wasSuccess) {
+ if(showerror)
+ element.title = bugIdHelper.strings.getFormattedString("invalidPage", [url]);
+ return;
+ }
+ var bug = xml.getElementsByTagName("bug");
+ if(bug && bug[0] && bug[0].hasAttribute("error")) {
+ var error = bug[0].getAttribute("error");
+ if(showerror)
+ element.title = bugIdHelper.strings.getFormattedString("invalidId",
+ [bugIdHelper.userUrl, error]);
+ return;
+ }
+ var tooltip = [];
+ if(bugIdHelper.getBoolPref("tooltip.showid"))
+ tooltip.push(bugIdHelper.strings.getString("bug") + " " +
+ bugIdHelper.bugAttribute(xml, "bug_id"));
+ if(bugIdHelper.getBoolPref("tooltip.showstat")) {
+ var status = bugIdHelper.bugAttribute(xml, "bug_status");
+ var reso = bugIdHelper.bugAttribute(xml, "resolution");
+ if(reso)
+ tooltip.push(status + " " + reso);
+ else
+ tooltip.push(status);
+ }
+ if(bugIdHelper.getBoolPref("tooltip.showcomp")) {
+ var prod = bugIdHelper.bugAttribute(xml, "product");
+ var comp = bugIdHelper.bugAttribute(xml, "component");
+ tooltip.push(prod + "/" + comp);
+ }
+ if(bugIdHelper.getBoolPref("tooltip.showdate"))
+ tooltip.push(bugIdHelper.toDate(bugIdHelper.bugAttribute(xml, "creation_ts")));
+ if(bugIdHelper.getBoolPref("tooltip.showassign"))
+ tooltip.push(bugIdHelper.bugAttribute(xml, "assigned_to"));
+ if(bugIdHelper.getBoolPref("tooltip.showdesc"))
+ tooltip.push(bugIdHelper.bugAttribute(xml, "short_desc"));
+
+ if(bugIdHelper.getBoolPref("link.strikethrough")) {
+ var reso = bugIdHelper.bugAttribute(xml, "resolution");
+ if(bugIdHelper.strikeResos.indexOf(reso) != -1)
+ element.style.textDecoration = "underline line-through";
+ }
+
+ /* set title attribute to tooltip text */
+ element.title = tooltip.join(" -- ");
+ });
+ },
+
+ setComment : function(element, url, cid) {
+ this.xhr(url,
+ function(wasSuccess, xml) {
+ if(!bugIdHelper) // this happens sometimes
+ return;
+ var showerror = bugIdHelper.getBoolPref("tooltip.showerror");
+ if(!wasSuccess) {
+ if(showerror)
+ element.title = bugIdHelper.strings.getFormattedString("invalidPage", [url]);
+ return;
+ }
+ var bug = xml.getElementsByTagName("bug");
+ if(bug && bug[0] && bug[0].hasAttribute("error")) {
+ var error = bug[0].getAttribute("error");
+ if(showerror)
+ element.title = bugIdHelper.strings.getFormattedString("invalidId",
+ [bugIdHelper.userUrl, error]);
+ return;
+ }
+ /* set title attribute to comment text */
+ var comment = xml.getElementsByTagName("long_desc")[cid];
+ if(comment) {
+ var text = bugIdHelper.bugAttribute(comment, "thetext");
+ var tooltip = "";
+ if(bugIdHelper.getBoolPref("tooltip.showcommenter"))
+ tooltip += bugIdHelper.bugAttribute(comment, "who") + " -- ";
+ element.title = tooltip + text.substring(0, Math.min(text.length, 180)) + " ...";
+ }
+ });
+ },
+
+ /* Adapted from browser.js - Firefox. Adds full tooltip support to Thunderbird content */
+ fillTBirdTooltip : function(tipElement) {
+ var retVal = false;
+ if (tipElement.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul")
+ return retVal;
+ const XLinkNS = "http://www.w3.org/1999/xlink";
+ var titleText = null;
+ var XLinkTitleText = null;
+ var direction = tipElement.ownerDocument.dir;
+
+ while (!titleText && !XLinkTitleText && tipElement) {
+ if (tipElement.nodeType == Node.ELEMENT_NODE) {
+ titleText = tipElement.getAttribute("title");
+ XLinkTitleText = tipElement.getAttributeNS(XLinkNS, "title");
+ var defView = tipElement.ownerDocument.defaultView;
+ // Work around bug 350679: "Tooltips can be fired in documents with no view"
+ if (!defView)
+ return retVal;
+ direction = defView.getComputedStyle(tipElement, "")
+ .getPropertyValue("direction");
+ }
+ tipElement = tipElement.parentNode;
+ }
+
+ var tipNode = document.getElementById("bugidTooltip");
+ tipNode.style.direction = direction;
+
+ for each (var t in [titleText, XLinkTitleText]) {
+ if (t && /\S/.test(t)) {
+ // Per HTML 4.01 6.2 (CDATA section), literal CRs and tabs should be
+ // replaced with spaces, and LFs should be removed entirely
+ t = t.replace(/[\r\t]/g, ' ');
+ t = t.replace(/\n/g, '');
+
+ tipNode.setAttribute("label", t);
+ retVal = true;
+ }
+ }
+ return retVal;
+ },
+
+ /*--- utility functions ---*/
+ toBugzillaDomain : function (fragment) {
+ var matches = fragment.match(this.baseUrlExp);
+ if(matches)
+ return "https://" + matches[1] + "/";
+ },
+
+ toBaseUrl : function (fragment) {
+ var matches = fragment.match(this.baseUrlExp);
+ if(matches)
+ return "http://" + matches[1] + "/show_bug.cgi?";
+ },
+
+ toDomainRegex : function(userDomain) {
+ if(userDomain.indexOf("://") != -1)
+ return new RegExp("^" + userDomain);
+ return new RegExp("^(?:https?|file):\/\/(www\.)?" + userDomain);
+ },
+
+ toDomains : function(urlStr) {
+ var urls = urlStr.split(/[\s,;]+/);
+ var domains = [];
+ for(var i = 0, len = urls.length; i < len; i++)
+ domains.push(this.toDomainRegex(urls[i]));
+ return domains;
+ },
+
+ /* return true if can linkify and add tooltips to this document */
+ canBugify : function(doc) {
+ if(!doc.location || doc.location.href.indexOf("about:") == 0)
+ return false;
+ if(!this.getBoolPref("linkify") && !this.getBoolPref("tooltipify"))
+ return false;
+ if(this.prefService.getBoolPref("extensions.bugid.filter")) {
+ var isValidDomain = false;
+ for(var i = 0, len = this.domainExps.length; i < len; i++) {
+ if(this.domainExps[i].test(doc.location.href))
+ isValidDomain = true;
+ }
+ return isValidDomain;
+ }
+ return true;
+ },
+
+ canSetHref : function(doc, elem) {
+ return !this.xpathBool(doc,
+ "boolean(ancestor-or-self::*[@href])", elem);
+ },
+
+ canSetTitle : function(doc, elem) {
+ return !this.xpathBool(doc,
+ "boolean(ancestor-or-self::*[@title or @onmouseover])", elem);
+ },
+
+ canLink : function(doc, elem) {
+ return !this.xpathBool(doc, "boolean(ancestor-or-self::*[@class='__firefox_bugidhelper'])");
+ },
+
+ getBoolPref : function(pref) {
+ return this.prefService.getBoolPref("extensions.bugid." + pref);
+ },
+
+ getLogin : function() {
+ if ("@mozilla.org/passwordmanager;1" in Components.classes) {
+ // Thunderbird 2
+ var passwordManager = Components.classes["@mozilla.org/passwordmanager;1"]
+ .getService(Components.interfaces.nsIPasswordManager);
+ var e = passwordManager.enumerator;
+ while (e.hasMoreElements()) {
+ var loginInfo = e.getNext().QueryInterface(Components.interfaces.nsIPassword);
+ if (loginInfo.host == bugIdHelper.hostUrl)
+ return {username: loginInfo.user, password: loginInfo.password};
+ }
+ }
+ else if ("@mozilla.org/login-manager;1" in Components.classes) {
+ // Thunderbird 3, Firefox 3
+ var loginManager = Components.classes["@mozilla.org/login-manager;1"]
+ .getService(Components.interfaces.nsILoginManager);
+
+ var logins = loginManager.findLogins({}, bugIdHelper.hostUrl, "", null);
+ if(logins.length > 0)
+ return {username: logins[0].username, password: logins[0].password};
+ }
+ return {username:'', password:''};
+ },
+
+ xhr : function (url, callback) {
+ var req = new XMLHttpRequest();
+ req.open('GET', url, true);
+ req.onreadystatechange = function (event) {
+ if (req.readyState == 4) {
+ if(req.status == 200)
+ callback(true, req.responseXML);
+ else
+ callback(false);
+ }
+ };
+ req.send(null);
+ },
+
+ bugAttribute : function(target, tag) {
+ var elements = target.getElementsByTagName(tag);
+ if(elements.length)
+ return elements[0].firstChild.data;
+ else return '';
+ },
+
+ toDate : function(bugDate) {
+ var matches = bugDate.match(this.dateExp);
+ return matches[0];
+ },
+
+ xpathNodes : function(doc, expression, element) {
+ var target = element || doc;
+ var results = [];
+ var query = doc.evaluate(expression, target,
+ null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ for (var i = 0, len = query.snapshotLength; i < len; i++)
+ results.push(query.snapshotItem(i));
+ return results;
+ },
+
+ xpathBool : function(doc, expression, element) {
+ var target = element || doc;
+ return doc.evaluate(expression, target, null, XPathResult.BOOLEAN_TYPE, null).booleanValue;
+ },
+
+ xpathString : function(doc, expression, element) {
+ var target = element || doc;
+ return doc.evaluate(expression, target, null, XPathResult.STRING_TYPE, null).stringValue;
+ }
+}
55 chrome/content/tbirdOverlay.xul
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ***** 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 Bug Id Helper.
+ -
+ - The Initial Developer of the Original Code is
+ - Heather Arthur.
+ - Portions created by the Initial Developer are Copyright (C) 2009
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - 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 ***** -->
+<!DOCTYPE overlay SYSTEM "chrome://bugid/locale/bugid.dtd">
+<overlay id="bugid-overlay"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/x-javascript" src="chrome://bugid/content/overlay.js"/>
+ <script type="application/x-javascript" src="chrome://bugid/content/bugzillaRPC.js"/>
+
+ <stringbundleset id="stringbundleset">
+ <stringbundle id="bugid-strings" src="chrome://bugid/locale/bugid.properties"/>
+ </stringbundleset>
+
+ <toolbox id="mail-toolbox">
+ <tooltip id="bugidTooltip" onpopupshowing="return bugIdHelper.fillTBirdTooltip(document.tooltipNode);"/>
+ </toolbox>
+
+ <browser id="messagepane" tooltip="bugidTooltip"/>
+
+</overlay>
+
1 chrome/locale/en-US/bugid.dtd
@@ -0,0 +1 @@
+<!ENTITY bugid.accesskey "B">
6 chrome/locale/en-US/bugid.properties
@@ -0,0 +1,6 @@
+contextItem=Open Bug %S
+bug=Bug
+invalidPage=Invalid Bugzilla URL: %S
+invalidId=%S -- Error: %S
+anchorClass=__bugidhelper
+
24 chrome/locale/en-US/prefwindow.dtd
@@ -0,0 +1,24 @@
+<!ENTITY prefwindow.title "Bug ID Helper preferences">
+<!ENTITY pane1.title "Bug ID Helper preferences">
+<!ENTITY linkifypref.label "Linkify Bug Ids/Urls">
+<!ENTITY strikepref.label "Strikethrough Bugs With Resolution:">
+<!ENTITY loginpref.label "Login (opt):">
+<!ENTITY loginpref.tooltip "Login for tooltip info on password-protected bugs">
+<!ENTITY passpref.label "Password:">
+<!ENTITY divertpref.label "Load Links in New Tab">
+<!ENTITY tooltippref.label "Add Tooltips to Bugzilla Links">
+<!ENTITY toolidpref.label "Show Id">
+<!ENTITY toolstatpref.label "Show Status/Resolution">
+<!ENTITY tooldescpref.label "Show Short Description">
+<!ENTITY tooldatepref.label "Show Date Reported">
+<!ENTITY toolassignpref.label "Show Assignee">
+<!ENTITY toolcomppref.label "Show Product/Component">
+<!ENTITY toolcommpref.label "Show Commenter">
+<!ENTITY toolerrorpref.label "Show Error">
+<!ENTITY toolerrorpref.tooltip "Display error message in tooltip if invalid bug id">
+<!ENTITY toolcommpref.tooltip "Display commenter in tooltip over urls with named comment anchor">
+<!ENTITY filterpref.label "Only Add Links/Tooltips to These Domains:">
+<!ENTITY urlpref.label "Bugzilla URL (e.g. bugzilla.mozilla.org):">
+<!ENTITY stringpref.accesskey "U">
+<!ENTITY intpref.accesskey "T">
+<!ENTITY checkboolpref.accesskey "L">
12 chrome/skin/bugidhelper.css
@@ -0,0 +1,12 @@
+/* preference window */
+.subpref {
+ padding-left: 20px;
+}
+
+.category-prime {
+ padding: 5px 0 5px 0;
+}
+
+.category {
+ padding: 4px 0 4px 0;
+}
BIN chrome/skin/bugzilla.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN chrome/skin/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 defaults/preferences/preferences.js
@@ -0,0 +1,19 @@
+pref("extensions.bugid.url", "bugzilla.mozilla.org");
+pref("extensions.bugid.linkify", true);
+pref("extensions.bugid.link.diverted", false);
+pref("extensions.bugid.link.strikethrough", true);
+pref("extensions.bugid.link.strike.resos", "FIXED, WORKSFORME");
+pref("extensions.bugid.tooltipify", true);
+pref("extensions.bugid.tooltip.showid", true);
+pref("extensions.bugid.tooltip.showstat", false);
+pref("extensions.bugid.tooltip.showdesc", true);
+pref("extensions.bugid.tooltip.showdate", false);
+pref("extensions.bugid.tooltip.showcomp", false);
+pref("extensions.bugid.tooltip.showerror", true);
+pref("extensions.bugid.tooltip.showassign", false);
+pref("extensions.bugid.tooltip.showcommenter", true);
+pref("extensions.bugid.filter", false);
+pref("extensions.bugid.whitelist", "mxr.mozilla.org, www.google.com");
+
+
+
34 install.rdf
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>bugid@linkification.org</em:id>
+ <em:name>Bug Id Helper</em:name>
+ <em:version>1.3.1</em:version>
+ <em:type>2</em:type>
+ <em:creator>Heather Arthur</em:creator>
+ <em:description>Bugzilla bug id linkifier</em:description>
+ <em:optionsURL>chrome://bugid/content/options.xul</em:optionsURL>
+ <em:iconURL>chrome://bugid/skin/icon.png</em:iconURL>
+
+ <!-- firefox -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.0</em:minVersion>
+ <em:maxVersion>3.6a1pre</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+
+ <!-- thunderbird -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
+ <em:minVersion>2.0</em:minVersion>
+ <em:maxVersion>3.1a1pre</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+
+
+ </Description>
+</RDF>
8 zipexclude.lst
@@ -0,0 +1,8 @@
+*.svn*
+*.DS_Store*
+*.xpi*
+*~
+*test*
+*.txt*
+zipexclude.lst
+*.hg*

0 comments on commit 64c22b6

Please sign in to comment.