Launching commitfest.postgresql.org
2009/7/7 Brendan Jurd <direvus@gmail.com>:
We're now about a week away from the start of the July 2009
commitfest, and we need to make a decision about whether to start
using http://commitfest.postgresql.org to manage it, or punt to the
next commitfest and continue to use the wiki for July.
Thank you to everyone who commented in the parent thread. Robert
feels we're ready to go ahead and commission the new commitfest app
for the upcoming 'fest beginning 15 July, and he's asked me to do the
honours.
So, effective immediately, please treat
http://commitfest.postgresql.org as your authoritative source for
commitfests going forward.
The app is written and maintained by Robert Haas, and the source code
is located at:
web: http://git.postgresql.org/gitweb?p=pgcommitfest.git
git: git://git.postgresql.org/git/pgcommitfest.git
Your login details for the app == your community login == your wiki login.
The overall workflow, structure and layout of the commitfest is pretty
much the same. The only material difference you'll notice is that
you're filling out forms with discrete fields instead of delicately
shunting curly braces and pipes around in a giant textarea.
Closed commitfests from the 8.4 cycle will continue to live in their
current form on the wiki.
The wiki page for 2009-First will shortly be replaced by a brief
boilerplate pointing to the new app. The patches currently on that
page will be copied to an archive page at
http://wiki.postgresql.org/wiki/CommitFest_2009-First_Archive.
I would prefer to change the CommitFestOpen and CommitFestInProgress
redirects on the wiki to point at the app, but wiki redirects can only
link to other articles in the same wiki; external URLs are not
allowed. So both of these pages will continue to point at 2009-First,
which will instruct the user to go to the app.
I will be working my way through the Developer Information pages on
the wiki, updating as necessary. If you notice a page on the wiki
with out-of-date information regarding commitfests, feel free to ping
me about it (or fix it yourself; it is a wiki after all).
Cheers,
BJ
On Thursday 09 July 2009 19:06:35 Brendan Jurd wrote:
Your login details for the app == your community login == your wiki login.
One thing I forgot to mention: Please set up an SSL server certificate around
the login page.
On Jul 9, 2009, at 5:07 PM, Peter Eisentraut <peter_e@gmx.net> wrote:
On Thursday 09 July 2009 19:06:35 Brendan Jurd wrote:
Your login details for the app == your community login == your wiki
login.One thing I forgot to mention: Please set up an SSL server
certificate around
the login page.
Who will provide and pay for it?
...Robert
On Thu, Jul 9, 2009 at 11:31 PM, Robert Haas<robertmhaas@gmail.com> wrote:
On Jul 9, 2009, at 5:07 PM, Peter Eisentraut <peter_e@gmx.net> wrote:
On Thursday 09 July 2009 19:06:35 Brendan Jurd wrote:
Your login details for the app == your community login == your wiki
login.One thing I forgot to mention: Please set up an SSL server certificate
around
the login page.Who will provide and pay for it?
We have a wildcard cert for the domain. I'm going on vacation at the
weekend, and have to wrap up a bunch of stuff at work tomorrow, but if
you talk nicely to Stefan...
--
Dave Page
EnterpriseDB UK: http://www.enterprisedb.com
On Jul 9, 2009, at 5:53 PM, Dave Page <dpage@pgadmin.org> wrote:
On Thu, Jul 9, 2009 at 11:31 PM, Robert Haas<robertmhaas@gmail.com>
wrote:On Jul 9, 2009, at 5:07 PM, Peter Eisentraut <peter_e@gmx.net> wrote:
On Thursday 09 July 2009 19:06:35 Brendan Jurd wrote:
Your login details for the app == your community login == your wiki
login.One thing I forgot to mention: Please set up an SSL server
certificate
around
the login page.Who will provide and pay for it?
We have a wildcard cert for the domain. I'm going on vacation at the
weekend, and have to wrap up a bunch of stuff at work tomorrow, but if
you talk nicely to Stefan...
Stefan, you are mighty and have powerful administration skills.
Indeed, you have knowledge of many passwords that are hidden from the
foolish. I humbly beseech you for a copy of the aforementioned cert on
coridan...
Is that enough? I can go on... :-)
...Robert
On Fri, Jul 10, 2009 at 2:23 AM, Robert Haas<robertmhaas@gmail.com> wrote:
We have a wildcard cert for the domain. I'm going on vacation at the
weekend, and have to wrap up a bunch of stuff at work tomorrow, but if
you talk nicely to Stefan...Stefan, you are mighty and have powerful administration skills. Indeed, you
have knowledge of many passwords that are hidden from the foolish. I humbly
beseech you for a copy of the aforementioned cert on coridan...Is that enough? I can go on... :-)
Hey, that's really very good. Feel free to continue though, it's quite
amusing :-)
--
Dave Page
EnterpriseDB UK: http://www.enterprisedb.com
Robert Haas wrote:
On Jul 9, 2009, at 5:53 PM, Dave Page <dpage@pgadmin.org> wrote:
On Thu, Jul 9, 2009 at 11:31 PM, Robert Haas<robertmhaas@gmail.com>
wrote:On Jul 9, 2009, at 5:07 PM, Peter Eisentraut <peter_e@gmx.net> wrote:
On Thursday 09 July 2009 19:06:35 Brendan Jurd wrote:
Your login details for the app == your community login == your wiki
login.One thing I forgot to mention: Please set up an SSL server certificate
around
the login page.Who will provide and pay for it?
We have a wildcard cert for the domain. I'm going on vacation at the
weekend, and have to wrap up a bunch of stuff at work tomorrow, but if
you talk nicely to Stefan...Stefan, you are mighty and have powerful administration skills. Indeed,
you have knowledge of many passwords that are hidden from the foolish. I
humbly beseech you for a copy of the aforementioned cert on coridan...Is that enough? I can go on... :-)
not enough for getting it done immediately - but I will take a look
later today...
Stefan
Stefan Kaltenbrunner wrote:
Robert Haas wrote:
On Jul 9, 2009, at 5:53 PM, Dave Page <dpage@pgadmin.org> wrote:
On Thu, Jul 9, 2009 at 11:31 PM, Robert Haas<robertmhaas@gmail.com>
wrote:On Jul 9, 2009, at 5:07 PM, Peter Eisentraut <peter_e@gmx.net> wrote:
On Thursday 09 July 2009 19:06:35 Brendan Jurd wrote:
Your login details for the app == your community login == your wiki
login.One thing I forgot to mention: Please set up an SSL server certificate
around
the login page.Who will provide and pay for it?
We have a wildcard cert for the domain. I'm going on vacation at the
weekend, and have to wrap up a bunch of stuff at work tomorrow, but if
you talk nicely to Stefan...Stefan, you are mighty and have powerful administration skills.
Indeed, you have knowledge of many passwords that are hidden from the
foolish. I humbly beseech you for a copy of the aforementioned cert on
coridan...Is that enough? I can go on... :-)
not enough for getting it done immediately - but I will take a look
later today...
https support is now available on that jail (maybe we should simply
always redirect to the https url on all pages).
I also rearranged some of the configuration files as well as fixing a
few omissions from the initial install(like erm - where the hell are the
backups?!) so any new breakage is likely mine :)
Stefan
On Friday 10 July 2009 19:35:56 Stefan Kaltenbrunner wrote:
https support is now available on that jail (maybe we should simply
always redirect to the https url on all pages).
Yeah, at least the login page should be redirected to https. Right now, you
have to detect the SSL support by guessing and manually manipulating the URL.
On Mon, Jul 13, 2009 at 8:47 AM, Peter Eisentraut<peter_e@gmx.net> wrote:
On Friday 10 July 2009 19:35:56 Stefan Kaltenbrunner wrote:
https support is now available on that jail (maybe we should simply
always redirect to the https url on all pages).Yeah, at least the login page should be redirected to https. Right now, you
have to detect the SSL support by guessing and manually manipulating the URL.
+1 for redirecting the whole site. I don't think the extra CPU load
of SSL is going to bother anyone for the amount of traffic we're
likely to have on that site. Simplicity is good.
...Robert
2009/7/14 Robert Haas <robertmhaas@gmail.com>:
+1 for redirecting the whole site. I don't think the extra CPU load
of SSL is going to bother anyone for the amount of traffic we're
likely to have on that site. Simplicity is good.
+1 for SSL on all pages from me also.
Cheers,
BJ
Brendan Jurd wrote:
2009/7/14 Robert Haas <robertmhaas@gmail.com>:
+1 for redirecting the whole site. I don't think the extra CPU load
of SSL is going to bother anyone for the amount of traffic we're
likely to have on that site. Simplicity is good.+1 for SSL on all pages from me also.
yeah fine with me - who is going to do this?
Stefan
On Jul 14, 2009, at 12:21 PM, Stefan Kaltenbrunner <stefan@kaltenbrunner.cc
wrote:
Brendan Jurd wrote:
2009/7/14 Robert Haas <robertmhaas@gmail.com>:
+1 for redirecting the whole site. I don't think the extra CPU load
of SSL is going to bother anyone for the amount of traffic we're
likely to have on that site. Simplicity is good.+1 for SSL on all pages from me also.
yeah fine with me - who is going to do this?
If you have time, that would be great; if not I will do it.
...Robert
Robert Haas wrote:
On Jul 14, 2009, at 12:21 PM, Stefan Kaltenbrunner
<stefan@kaltenbrunner.cc> wrote:Brendan Jurd wrote:
2009/7/14 Robert Haas <robertmhaas@gmail.com>:
+1 for redirecting the whole site. I don't think the extra CPU load
of SSL is going to bother anyone for the amount of traffic we're
likely to have on that site. Simplicity is good.+1 for SSL on all pages from me also.
yeah fine with me - who is going to do this?
If you have time, that would be great; if not I will do it.
well you just volunteered...
have fun :)
Stefan
Robert, Brendan,
Here's another feature request -- please make message-ids visible so
that they can be copy and pasted into one's email client.
Thanks,
--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
On Tue, Jul 14, 2009 at 5:33 PM, Stefan
Kaltenbrunner<stefan@kaltenbrunner.cc> wrote:
If you have time, that would be great; if not I will do it.
well you just volunteered...
I was trying hard not to.
But, done.
...Robert
Robert,
BTW, the new commitfest software is great. Easily a 75% reduction in
time required to track reviewing activity.
--
Josh Berkus
PostgreSQL Experts Inc.
www.pgexperts.com
On Thu, 2009-07-16 at 21:31 -0700, Josh Berkus wrote:
Robert,
BTW, the new commitfest software is great. Easily a 75% reduction in
time required to track reviewing activity.
I agree. It is much better. I have one suggestion. Make the headings
sortable (except maybe for patch name). That way if I want to see what
patches Tom is working on, I can easily get a grouping or more
importantly patches that nobody is working on.
Joshua D. Drake
--
Josh Berkus
PostgreSQL Experts Inc.
www.pgexperts.com
--
PostgreSQL - XMPP: jdrake@jabber.postgresql.org
Consulting, Development, Support, Training
503-667-4564 - http://www.commandprompt.com/
The PostgreSQL Company, serving since 1997
On Fri, Jul 17, 2009 at 10:36:14AM -0700, Joshua D. Drake wrote:
On Thu, 2009-07-16 at 21:31 -0700, Josh Berkus wrote:
Robert,
BTW, the new commitfest software is great. Easily a 75% reduction in
time required to track reviewing activity.I agree. It is much better. I have one suggestion. Make the headings
sortable (except maybe for patch name).
Here's a patch for that :) Untested, because I couldn't figure out
how to set up a commitfest on my machine :(
Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com
Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate
Attachments:
add_sorttable.difftext/plain; charset=utf8Download
diff --git a/html/layout/js/sorttable.js b/html/layout/js/sorttable.js
new file mode 100644
index 0000000..25bccb2
--- /dev/null
+++ b/html/layout/js/sorttable.js
@@ -0,0 +1,493 @@
+/*
+ SortTable
+ version 2
+ 7th April 2007
+ Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
+
+ Instructions:
+ Download this file
+ Add <script src="sorttable.js"></script> to your HTML
+ Add class="sortable" to any table you'd like to make sortable
+ Click on the headers to sort
+
+ Thanks to many, many people for contributions and suggestions.
+ Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
+ This basically means: do what you want with it.
+*/
+
+
+var stIsIE = /*@cc_on!@*/false;
+
+sorttable = {
+ init: function() {
+ // quit if this function has already been called
+ if (arguments.callee.done) return;
+ // flag this function so we don't do the same thing twice
+ arguments.callee.done = true;
+ // kill the timer
+ if (_timer) clearInterval(_timer);
+
+ if (!document.createElement || !document.getElementsByTagName) return;
+
+ sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
+
+ forEach(document.getElementsByTagName('table'), function(table) {
+ if (table.className.search(/\bsortable\b/) != -1) {
+ sorttable.makeSortable(table);
+ }
+ });
+
+ },
+
+ makeSortable: function(table) {
+ if (table.getElementsByTagName('thead').length == 0) {
+ // table doesn't have a tHead. Since it should have, create one and
+ // put the first table row in it.
+ the = document.createElement('thead');
+ the.appendChild(table.rows[0]);
+ table.insertBefore(the,table.firstChild);
+ }
+ // Safari doesn't support table.tHead, sigh
+ if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
+
+ if (table.tHead.rows.length != 1) return; // can't cope with two header rows
+
+ // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as
+ // "total" rows, for example). This is B&R, since what you're supposed
+ // to do is put them in a tfoot. So, if there are sortbottom rows,
+ // for backwards compatibility, move them to tfoot (creating it if needed).
+ sortbottomrows = [];
+ for (var i=0; i<table.rows.length; i++) {
+ if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {
+ sortbottomrows[sortbottomrows.length] = table.rows[i];
+ }
+ }
+ if (sortbottomrows) {
+ if (table.tFoot == null) {
+ // table doesn't have a tfoot. Create one.
+ tfo = document.createElement('tfoot');
+ table.appendChild(tfo);
+ }
+ for (var i=0; i<sortbottomrows.length; i++) {
+ tfo.appendChild(sortbottomrows[i]);
+ }
+ delete sortbottomrows;
+ }
+
+ // work through each column and calculate its type
+ headrow = table.tHead.rows[0].cells;
+ for (var i=0; i<headrow.length; i++) {
+ // manually override the type with a sorttable_type attribute
+ if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col
+ mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);
+ if (mtch) { override = mtch[1]; }
+ if (mtch && typeof sorttable["sort_"+override] == 'function') {
+ headrow[i].sorttable_sortfunction = sorttable["sort_"+override];
+ } else {
+ headrow[i].sorttable_sortfunction = sorttable.guessType(table,i);
+ }
+ // make it clickable to sort
+ headrow[i].sorttable_columnindex = i;
+ headrow[i].sorttable_tbody = table.tBodies[0];
+ dean_addEvent(headrow[i],"click", function(e) {
+
+ if (this.className.search(/\bsorttable_sorted\b/) != -1) {
+ // if we're already sorted by this column, just
+ // reverse the table, which is quicker
+ sorttable.reverse(this.sorttable_tbody);
+ this.className = this.className.replace('sorttable_sorted',
+ 'sorttable_sorted_reverse');
+ this.removeChild(document.getElementById('sorttable_sortfwdind'));
+ sortrevind = document.createElement('span');
+ sortrevind.id = "sorttable_sortrevind";
+ sortrevind.innerHTML = stIsIE ? ' <font face="webdings">5</font>' : ' ▴';
+ this.appendChild(sortrevind);
+ return;
+ }
+ if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
+ // if we're already sorted by this column in reverse, just
+ // re-reverse the table, which is quicker
+ sorttable.reverse(this.sorttable_tbody);
+ this.className = this.className.replace('sorttable_sorted_reverse',
+ 'sorttable_sorted');
+ this.removeChild(document.getElementById('sorttable_sortrevind'));
+ sortfwdind = document.createElement('span');
+ sortfwdind.id = "sorttable_sortfwdind";
+ sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾';
+ this.appendChild(sortfwdind);
+ return;
+ }
+
+ // remove sorttable_sorted classes
+ theadrow = this.parentNode;
+ forEach(theadrow.childNodes, function(cell) {
+ if (cell.nodeType == 1) { // an element
+ cell.className = cell.className.replace('sorttable_sorted_reverse','');
+ cell.className = cell.className.replace('sorttable_sorted','');
+ }
+ });
+ sortfwdind = document.getElementById('sorttable_sortfwdind');
+ if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
+ sortrevind = document.getElementById('sorttable_sortrevind');
+ if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); }
+
+ this.className += ' sorttable_sorted';
+ sortfwdind = document.createElement('span');
+ sortfwdind.id = "sorttable_sortfwdind";
+ sortfwdind.innerHTML = stIsIE ? ' <font face="webdings">6</font>' : ' ▾';
+ this.appendChild(sortfwdind);
+
+ // build an array to sort. This is a Schwartzian transform thing,
+ // i.e., we "decorate" each row with the actual sort key,
+ // sort based on the sort keys, and then put the rows back in order
+ // which is a lot faster because you only do getInnerText once per row
+ row_array = [];
+ col = this.sorttable_columnindex;
+ rows = this.sorttable_tbody.rows;
+ for (var j=0; j<rows.length; j++) {
+ row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];
+ }
+ /* If you want a stable sort, uncomment the following line */
+ //sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
+ /* and comment out this one */
+ row_array.sort(this.sorttable_sortfunction);
+
+ tb = this.sorttable_tbody;
+ for (var j=0; j<row_array.length; j++) {
+ tb.appendChild(row_array[j][1]);
+ }
+
+ delete row_array;
+ });
+ }
+ }
+ },
+
+ guessType: function(table, column) {
+ // guess the type of a column based on its first non-blank row
+ sortfn = sorttable.sort_alpha;
+ for (var i=0; i<table.tBodies[0].rows.length; i++) {
+ text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
+ if (text != '') {
+ if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
+ return sorttable.sort_numeric;
+ }
+ // check for a date: dd/mm/yyyy or dd/mm/yy
+ // can have / or . or - as separator
+ // can be mm/dd as well
+ possdate = text.match(sorttable.DATE_RE)
+ if (possdate) {
+ // looks like a date
+ first = parseInt(possdate[1]);
+ second = parseInt(possdate[2]);
+ if (first > 12) {
+ // definitely dd/mm
+ return sorttable.sort_ddmm;
+ } else if (second > 12) {
+ return sorttable.sort_mmdd;
+ } else {
+ // looks like a date, but we can't tell which, so assume
+ // that it's dd/mm (English imperialism!) and keep looking
+ sortfn = sorttable.sort_ddmm;
+ }
+ }
+ }
+ }
+ return sortfn;
+ },
+
+ getInnerText: function(node) {
+ // gets the text we want to use for sorting for a cell.
+ // strips leading and trailing whitespace.
+ // this is *not* a generic getInnerText function; it's special to sorttable.
+ // for example, you can override the cell text with a customkey attribute.
+ // it also gets .value for <input> fields.
+
+ hasInputs = (typeof node.getElementsByTagName == 'function') &&
+ node.getElementsByTagName('input').length;
+
+ if (node.getAttribute("sorttable_customkey") != null) {
+ return node.getAttribute("sorttable_customkey");
+ }
+ else if (typeof node.textContent != 'undefined' && !hasInputs) {
+ return node.textContent.replace(/^\s+|\s+$/g, '');
+ }
+ else if (typeof node.innerText != 'undefined' && !hasInputs) {
+ return node.innerText.replace(/^\s+|\s+$/g, '');
+ }
+ else if (typeof node.text != 'undefined' && !hasInputs) {
+ return node.text.replace(/^\s+|\s+$/g, '');
+ }
+ else {
+ switch (node.nodeType) {
+ case 3:
+ if (node.nodeName.toLowerCase() == 'input') {
+ return node.value.replace(/^\s+|\s+$/g, '');
+ }
+ case 4:
+ return node.nodeValue.replace(/^\s+|\s+$/g, '');
+ break;
+ case 1:
+ case 11:
+ var innerText = '';
+ for (var i = 0; i < node.childNodes.length; i++) {
+ innerText += sorttable.getInnerText(node.childNodes[i]);
+ }
+ return innerText.replace(/^\s+|\s+$/g, '');
+ break;
+ default:
+ return '';
+ }
+ }
+ },
+
+ reverse: function(tbody) {
+ // reverse the rows in a tbody
+ newrows = [];
+ for (var i=0; i<tbody.rows.length; i++) {
+ newrows[newrows.length] = tbody.rows[i];
+ }
+ for (var i=newrows.length-1; i>=0; i--) {
+ tbody.appendChild(newrows[i]);
+ }
+ delete newrows;
+ },
+
+ /* sort functions
+ each sort function takes two parameters, a and b
+ you are comparing a[0] and b[0] */
+ sort_numeric: function(a,b) {
+ aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));
+ if (isNaN(aa)) aa = 0;
+ bb = parseFloat(b[0].replace(/[^0-9.-]/g,''));
+ if (isNaN(bb)) bb = 0;
+ return aa-bb;
+ },
+ sort_alpha: function(a,b) {
+ if (a[0]==b[0]) return 0;
+ if (a[0]<b[0]) return -1;
+ return 1;
+ },
+ sort_ddmm: function(a,b) {
+ mtch = a[0].match(sorttable.DATE_RE);
+ y = mtch[3]; m = mtch[2]; d = mtch[1];
+ if (m.length == 1) m = '0'+m;
+ if (d.length == 1) d = '0'+d;
+ dt1 = y+m+d;
+ mtch = b[0].match(sorttable.DATE_RE);
+ y = mtch[3]; m = mtch[2]; d = mtch[1];
+ if (m.length == 1) m = '0'+m;
+ if (d.length == 1) d = '0'+d;
+ dt2 = y+m+d;
+ if (dt1==dt2) return 0;
+ if (dt1<dt2) return -1;
+ return 1;
+ },
+ sort_mmdd: function(a,b) {
+ mtch = a[0].match(sorttable.DATE_RE);
+ y = mtch[3]; d = mtch[2]; m = mtch[1];
+ if (m.length == 1) m = '0'+m;
+ if (d.length == 1) d = '0'+d;
+ dt1 = y+m+d;
+ mtch = b[0].match(sorttable.DATE_RE);
+ y = mtch[3]; d = mtch[2]; m = mtch[1];
+ if (m.length == 1) m = '0'+m;
+ if (d.length == 1) d = '0'+d;
+ dt2 = y+m+d;
+ if (dt1==dt2) return 0;
+ if (dt1<dt2) return -1;
+ return 1;
+ },
+
+ shaker_sort: function(list, comp_func) {
+ // A stable sort function to allow multi-level sorting of data
+ // see: http://en.wikipedia.org/wiki/Cocktail_sort
+ // thanks to Joseph Nahmias
+ var b = 0;
+ var t = list.length - 1;
+ var swap = true;
+
+ while(swap) {
+ swap = false;
+ for(var i = b; i < t; ++i) {
+ if ( comp_func(list[i], list[i+1]) > 0 ) {
+ var q = list[i]; list[i] = list[i+1]; list[i+1] = q;
+ swap = true;
+ }
+ } // for
+ t--;
+
+ if (!swap) break;
+
+ for(var i = t; i > b; --i) {
+ if ( comp_func(list[i], list[i-1]) < 0 ) {
+ var q = list[i]; list[i] = list[i-1]; list[i-1] = q;
+ swap = true;
+ }
+ } // for
+ b++;
+
+ } // while(swap)
+ }
+}
+
+/* ******************************************************************
+ Supporting functions: bundled here to avoid depending on a library
+ ****************************************************************** */
+
+// Dean Edwards/Matthias Miller/John Resig
+
+/* for Mozilla/Opera9 */
+if (document.addEventListener) {
+ document.addEventListener("DOMContentLoaded", sorttable.init, false);
+}
+
+/* for Internet Explorer */
+/*@cc_on @*/
+/*@if (@_win32)
+ document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
+ var script = document.getElementById("__ie_onload");
+ script.onreadystatechange = function() {
+ if (this.readyState == "complete") {
+ sorttable.init(); // call the onload handler
+ }
+ };
+/*@end @*/
+
+/* for Safari */
+if (/WebKit/i.test(navigator.userAgent)) { // sniff
+ var _timer = setInterval(function() {
+ if (/loaded|complete/.test(document.readyState)) {
+ sorttable.init(); // call the onload handler
+ }
+ }, 10);
+}
+
+/* for other browsers */
+window.onload = sorttable.init;
+
+// written by Dean Edwards, 2005
+// with input from Tino Zijdel, Matthias Miller, Diego Perini
+
+// http://dean.edwards.name/weblog/2005/10/add-event/
+
+function dean_addEvent(element, type, handler) {
+ if (element.addEventListener) {
+ element.addEventListener(type, handler, false);
+ } else {
+ // assign each event handler a unique ID
+ if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++;
+ // create a hash table of event types for the element
+ if (!element.events) element.events = {};
+ // create a hash table of event handlers for each element/event pair
+ var handlers = element.events[type];
+ if (!handlers) {
+ handlers = element.events[type] = {};
+ // store the existing event handler (if there is one)
+ if (element["on" + type]) {
+ handlers[0] = element["on" + type];
+ }
+ }
+ // store the event handler in the hash table
+ handlers[handler.$$guid] = handler;
+ // assign a global event handler to do all the work
+ element["on" + type] = handleEvent;
+ }
+};
+// a counter used to create unique IDs
+dean_addEvent.guid = 1;
+
+function removeEvent(element, type, handler) {
+ if (element.removeEventListener) {
+ element.removeEventListener(type, handler, false);
+ } else {
+ // delete the event handler from the hash table
+ if (element.events && element.events[type]) {
+ delete element.events[type][handler.$$guid];
+ }
+ }
+};
+
+function handleEvent(event) {
+ var returnValue = true;
+ // grab the event object (IE uses a global event object)
+ event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
+ // get a reference to the hash table of event handlers
+ var handlers = this.events[event.type];
+ // execute each event handler
+ for (var i in handlers) {
+ this.$$handleEvent = handlers[i];
+ if (this.$$handleEvent(event) === false) {
+ returnValue = false;
+ }
+ }
+ return returnValue;
+};
+
+function fixEvent(event) {
+ // add W3C standard event methods
+ event.preventDefault = fixEvent.preventDefault;
+ event.stopPropagation = fixEvent.stopPropagation;
+ return event;
+};
+fixEvent.preventDefault = function() {
+ this.returnValue = false;
+};
+fixEvent.stopPropagation = function() {
+ this.cancelBubble = true;
+}
+
+// Dean's forEach: http://dean.edwards.name/base/forEach.js
+/*
+ forEach, version 1.0
+ Copyright 2006, Dean Edwards
+ License: http://www.opensource.org/licenses/mit-license.php
+*/
+
+// array-like enumeration
+if (!Array.forEach) { // mozilla already supports this
+ Array.forEach = function(array, block, context) {
+ for (var i = 0; i < array.length; i++) {
+ block.call(context, array[i], i, array);
+ }
+ };
+}
+
+// generic enumeration
+Function.prototype.forEach = function(object, block, context) {
+ for (var key in object) {
+ if (typeof this.prototype[key] == "undefined") {
+ block.call(context, object[key], key, object);
+ }
+ }
+};
+
+// character enumeration
+String.forEach = function(string, block, context) {
+ Array.forEach(string.split(""), function(chr, index) {
+ block.call(context, chr, index, string);
+ });
+};
+
+// globally resolve forEach enumeration
+var forEach = function(object, block, context) {
+ if (object) {
+ var resolve = Object; // default
+ if (object instanceof Function) {
+ // functions have a "length" property
+ resolve = Function;
+ } else if (object.forEach instanceof Function) {
+ // the object implements a custom forEach method so use that
+ object.forEach(block, context);
+ return;
+ } else if (typeof object == "string") {
+ // the object is a string
+ resolve = String;
+ } else if (typeof object.length == "number") {
+ // the object is array-like
+ resolve = Array;
+ }
+ resolve.forEach(object, block, context);
+ }
+};
+
diff --git a/template/commitfest_activity.tt2 b/template/commitfest_activity.tt2
index 358f2e9..80439aa 100644
--- a/template/commitfest_activity.tt2
+++ b/template/commitfest_activity.tt2
@@ -2,7 +2,7 @@
[% IF activity.size %]
<div class='tblBasic'>
-<table cellspacing='0' class='tblBasicGrey' style='width: 100%'>
+<table cellspacing='0' class='tblBasicGrey sortable' style='width: 100%'>
<tr class='firstrow'>
<th class='colFirst'>Time</th>
<th>User</th>
diff --git a/template/commitfest_form.tt2 b/template/commitfest_form.tt2
index 6733561..e2563af 100644
--- a/template/commitfest_form.tt2
+++ b/template/commitfest_form.tt2
@@ -1,7 +1,7 @@
<p></p>
<div class='tblBasic'>
-<table cellspacing='0' class='tblBasicGrey'>
+<table cellspacing='0' class='tblBasicGrey sortable'>
<tr class='firstrow'>
<td class='colFirst'>[% control.name.display_name_html %]</td>
<td class='colLast'>[% control.name.render %]</td>
diff --git a/template/commitfest_search.tt2 b/template/commitfest_search.tt2
index ec39ad4..edfe06f 100644
--- a/template/commitfest_search.tt2
+++ b/template/commitfest_search.tt2
@@ -19,7 +19,7 @@ as <b>Future</b>.</p>
<p><b>No CommitFests have been defined yet.</b></p>
[% ELSE %]
<div class='tblBasic'>
-<table cellspacing='0' class='tblBasicGrey'>
+<table cellspacing='0' class='tblBasicGrey sortable'>
<tr>
<th class='colFirst'>CommitFest Name</th>
<th class='colLast'>Status</th>
diff --git a/template/commitfest_topic_form.tt2 b/template/commitfest_topic_form.tt2
index f3a853c..d94b762 100644
--- a/template/commitfest_topic_form.tt2
+++ b/template/commitfest_topic_form.tt2
@@ -1,7 +1,7 @@
<p></p>
<div class='tblBasic'>
-<table cellspacing='0' class='tblBasicGrey'>
+<table cellspacing='0' class='tblBasicGrey sortable'>
<tr class='firstrow'>
<td class='colFirst'>[% control.name.display_name_html %]</td>
<td class='colLast'>[% control.name.render %]</td>
diff --git a/template/commitfest_topic_search.tt2 b/template/commitfest_topic_search.tt2
index 17c0e71..6be1aca 100644
--- a/template/commitfest_topic_search.tt2
+++ b/template/commitfest_topic_search.tt2
@@ -1,7 +1,7 @@
<p></p>
[% IF topic_list.size %]
<div class='tblBasic'>
-<table cellspacing='0' class='tblBasicGrey'>
+<table cellspacing='0' class='tblBasicGrey sortable'>
<tr class='firstrow'>
<th class='colFirst'>Topic</th>
<th>Sort Order</th>
diff --git a/template/commitfest_view.tt2 b/template/commitfest_view.tt2
index 7bb6296..f986f88 100644
--- a/template/commitfest_view.tt2
+++ b/template/commitfest_view.tt2
@@ -7,7 +7,7 @@ changes, click on the patch name.</p>
[% IF g.patch_list.size %]
<div class='tblBasic'>
-<table cellspacing='0' class='tblBasicGrey' style='width: 100%'>
+<table cellspacing='0' class='tblBasicGrey sortable' style='width: 100%'>
<tr class='firstrow'>
<th class='colFirst' style='width: 60%'>Patch Name</th>
<th>Status</th>
diff --git a/template/header.tt2 b/template/header.tt2
index 1563751..0583516 100644
--- a/template/header.tt2
+++ b/template/header.tt2
@@ -5,6 +5,7 @@
<title>PostgreSQL CommitFest Management[% IF title != '' %]: [% title | htmlsafe %][% END %]</title>
<style type="text/css" media="screen" title="Normal Text">@import url("/layout/css/blue/commitfest.css");</style>
<script type="text/javascript" src="/layout/js/geckostyle.js"></script>
+ <script type="text/javascript" src="/layout/js/sorttable.js"></script>
</head>
<body>
<table id="commitfestHeader">
@@ -24,7 +25,7 @@
</table>
<div id="commitfestContent">
- <table cellspacing='0' cellpadding='0' border='0' width='100%'>
+ <table cellspacing='0' cellpadding='0' border='0' width='100%' class='sortable'>
<tr>
<td><h1>[% title %]</h1></td>
[% IF link.size != 0 %]<td style='text-align: right; padding-left: 10px'>[% FOREACH l = link %]<a href='[% l.0 %]'[% IF l.2.defined %] onClick='return confirm("[% l.2 | htmlsafe %]")'[% END %]>[% l.1 | html %]</a>[% IF !loop.last %] - [% END %][% END %]</td>[% END %]
diff --git a/template/login.tt2 b/template/login.tt2
index e7f581d..e402f83 100644
--- a/template/login.tt2
+++ b/template/login.tt2
@@ -1,7 +1,7 @@
<p>Please log in using your community login user ID and password.</p>
<div class='tblBasic'>
-<table cellspacing='0' class='tblBasicGrey'>
+<table cellspacing='0' class='tblBasicGrey sortable'>
<tr class='firstrow'>
<td class='colFirst'>[% control.userid.display_name | htmlsafe %]</td>
<td class='colLast'>[% control.userid.render %]</td>
diff --git a/template/patch_bump.tt2 b/template/patch_bump.tt2
index da5730b..f54c80a 100644
--- a/template/patch_bump.tt2
+++ b/template/patch_bump.tt2
@@ -4,7 +4,7 @@
<p><b>No other CommitFests exist.</b></p>
[% ELSE %]
<div class='tblBasic'>
-<table cellspacing='0' class='tblBasicGrey'>
+<table cellspacing='0' class='tblBasicGrey sortable'>
<tr>
<th class='colFirst'>CommitFest Name</th>
<th class='colLast'>Status</th>
diff --git a/template/patch_comment_form.tt2 b/template/patch_comment_form.tt2
index f3e3e52..a419f15 100644
--- a/template/patch_comment_form.tt2
+++ b/template/patch_comment_form.tt2
@@ -3,7 +3,7 @@ from the mailing list archives, enter the message ID into the space
provided.</p>
<div class='tblBasic'>
-<table cellspacing='0' class='tblBasicGrey'>
+<table cellspacing='0' class='tblBasicGrey sortable'>
<tr class='firstrow'>
<td class='colFirst'>[% control.patch_comment_type.display_name_html %]</td>
<td class='colLast'>[% control.patch_comment_type.render %]</td>
diff --git a/template/patch_form.tt2 b/template/patch_form.tt2
index 91ed836..5023199 100644
--- a/template/patch_form.tt2
+++ b/template/patch_form.tt2
@@ -19,7 +19,7 @@ Topics</a> page and add one or more topics.</p>
[% END %]
<div class='tblBasic'>
-<table cellspacing='0' class='tblBasicGrey'>
+<table cellspacing='0' class='tblBasicGrey sortable'>
<tr class='firstrow'>
<td class='colFirst'>[% control.name.display_name_html %]</td>
<td class='colLast'>[% control.name.render %]</td>
diff --git a/template/patch_view.tt2 b/template/patch_view.tt2
index 6448011..228bae4 100644
--- a/template/patch_view.tt2
+++ b/template/patch_view.tt2
@@ -1,7 +1,7 @@
<p></p>
<div class='tblBasic'>
-<table cellspacing='0' class='tblBasicGrey'>
+<table cellspacing='0' class='tblBasicGrey sortable'>
<tr class='firstrow'>
<td class='colFirst'>CommitFest</td>
<td class='colLast'><a href='/action/commitfest_view?id=[% d.commitfest_id %]'>[% d.commitfest | htmlsafe %]</a></td>
On Fri, Jul 17, 2009 at 04:13:58PM -0700, David Fetter wrote:
On Fri, Jul 17, 2009 at 10:36:14AM -0700, Joshua D. Drake wrote:
On Thu, 2009-07-16 at 21:31 -0700, Josh Berkus wrote:
Robert,
BTW, the new commitfest software is great. Easily a 75%
reduction in time required to track reviewing activity.I agree. It is much better. I have one suggestion. Make the
headings sortable (except maybe for patch name).Here's a patch for that :) Untested, because I couldn't figure out
how to set up a commitfest on my machine :(
Sorry about the duplicate. It looked like the first had fallen into a
black hole :P
Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com
Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate