--- a/review/static/comments.js Sun Jun 13 02:45:53 2010 -0400
+++ b/review/static/comments.js Sun Jun 13 04:42:29 2010 -0400
@@ -1,3 +1,28 @@
+function RenderLineCommentForm(line, currNum) {
+ var comment_form = '\
+ <tr class="comment-form">\
+ <td colspan="3">\
+ <form id="id_comment-line-form_' + currNum + '" method="POST" action="">\
+ <span class="lastlinenumber disabled">' + currNum + '</span>\
+ <div class="field">\
+ <label class="infield" for="id_comment-line-form_' + currNum + '_body">Comment</label>\
+ <textarea id="id_comment-line-form_' + currNum + '_body" \
+ name="new-comment-body"></textarea>\
+ </div>\
+ \
+ <a class="submit button"><span>Post Comment</span></a>\
+ <a class="cancel-line button"><span>Cancel</span></a>\
+ \
+ <input type="hidden" name="filename" value="<<<FILENAME>>>" />\
+ <input class="lines" type="hidden" name="lines" value="<<<LINENUMBER>>>" />\
+ </form>\
+ </td>\
+ </tr>';
+ comment_form = comment_form.replace('<<<FILENAME>>>', line.closest(".file").find(".filename h3 a").html());
+ comment_form = comment_form.replace('<<<LINENUMBER>>>', currNum);
+ return comment_form;
+}
+
$(function() {
$(".activate a").click(function(event) {
@@ -12,6 +37,12 @@
return false;
});
+ $("a.cancel-line").live('click', function(event) {
+ $(event.target).closest(".diff").find(".chosen").removeClass("chosen");
+ $(event.target).closest("tr.comment-form").remove();
+ return false;
+ });
+
$("tr.comment").hover(function(event) {
var diff = $(event.target).closest(".diff");
var lines = $(event.target).find(".commentlines").html().split(",");
@@ -21,40 +52,73 @@
}, function(event) {
$(".viewing").removeClass("viewing");
});
-
- //$("span.cancel-line a").live("click", function(event) {
- //$(event.target).closest("tr").prev().removeClass("comment-line-selected").addClass("commentable");
- //$(event.target).closest("tr").remove();
- //return false;
- //});
-
- //$("tr.rem.commentable,tr.add.commentable,tr.con.commentable").live("click", function(event) {
- //$(event.target).closest("tr").addClass("comment-line-selected").removeClass("commentable");
- //var filename = $(event.target).closest("tr").find(".line-data").children(".filename").first().text();
- //var linenumber = $(event.target).closest("tr").find(".line-data").children(".linenumber").first().html();
-
- //var comment_form = '<tr class="comment-line">\n\
- //<td>\n\
- //<form id="comment-line-form" method="post" action="">\n\
- //<div class="field">\n\
- //<label for="body">Add a comment on this line:</label>\n\
- //<textarea cols="60" rows="6" name="new-comment-body"></textarea>\n\
- //</div>\n\
- //<div class="buttons">\n\
- //<input type="submit" class="button" value="Submit" />\n\
- //<span class="cancel-line"><a href="">Cancel</a></span>\n\
- //</div>\n\
- //<input type="hidden" name="filename" value="<<<FILENAME>>>" />\n\
- //<input type="hidden" name="lines" value="<<<LINENUMBER>>>" />\n\
- //</form>\n\
- //</td>\n\
- //</tr>';
- //comment_form = comment_form.replace('<<<FILENAME>>>', filename);
- //comment_form = comment_form.replace('<<<LINENUMBER>>>', linenumber);
-
- //$(event.target).closest("tr").after(comment_form);
- //return false;
- //});
+
+ var lastSelected = null;
+
+ $(".commentable").click(function(event) {
+ var currNum = parseInt($(this).find(".linenumber").html());
+ var diff = $(this).closest(".diff");
+
+ if ($(this).hasClass("chosen")) {
+ $(this).removeClass("chosen");
+
+ var newLines = "";
+ jQuery.each(diff.find(".chosen .linenumber"), function() {
+ newLines += $(this).html() + ",";
+ });
+ diff.find(".comment-form form .lines").val(newLines);
+
+ lastSelected = null;
+ return false;
+ }
+
+ if (event.shiftKey && lastSelected) {
+ if (lastSelected && jQuery.contains(diff.get(0), lastSelected.get(0))) {
+ var lastNum = parseInt(lastSelected.find(".linenumber").html());
+ if (lastNum > currNum) {
+ for (i = currNum; i < lastNum; i++) {
+ diff.find(".line-" + i).addClass("chosen");
+ }
+ } else {
+ for (i = currNum; i > lastNum; i--) {
+ diff.find(".line-" + i).addClass("chosen");
+ }
+ }
+ }
+ } else {
+ $(this).addClass("chosen");
+ }
+ lastSelected = $(this);
+
+ var lines_chosen = diff.find(".chosen");
+ var last_line = lines_chosen.last();
+ var existing_forms = diff.find(".comment-form");
+
+ if (existing_forms.length) {
+ var existing_form = existing_forms.last();
+ var existing_form_line_number = parseInt(existing_form.find(".lastlinenumber").html());
+
+ if (existing_form_line_number < currNum) {
+ existing_forms.remove();
+
+ var comment_form = RenderLineCommentForm($(this), currNum);
+ $(this).after(comment_form);
+ diff.find("label").inFieldLabels();
+ }
+
+ var newLines = "";
+ jQuery.each(diff.find(".chosen .linenumber"), function() {
+ newLines += $(this).html() + ",";
+ });
+ diff.find(".comment-form form .lines").val(newLines);
+ } else {
+ var comment_form = RenderLineCommentForm($(this), currNum);
+ $(this).after(comment_form);
+ diff.find("label").inFieldLabels();
+ }
+
+ return false;
+ });
$("label.infield").inFieldLabels();
});
--- a/review/static/style.css Sun Jun 13 02:45:53 2010 -0400
+++ b/review/static/style.css Sun Jun 13 04:42:29 2010 -0400
@@ -11,6 +11,9 @@
* html .group, *:first-child + html .group {
zoom: 1;
}
+html {
+ overflow-y: scroll;
+}
html, body {
background-color: #edecc7;
background: #edecc7 url('bg.png') top left repeat;
@@ -65,6 +68,7 @@
}
body .header .remotes form a {
margin-right: 3px;
+ cursor: pointer;
font: bold 12px "Helvetica Neue", HelveticaNeue, Arial, Helvetica, sans-serif;
color: #212000;
line-height: 1.45;
@@ -243,6 +247,7 @@
width: 100%;
}
#changeset .content .activate a {
+ cursor: pointer;
font: bold 12px "Helvetica Neue", HelveticaNeue, Arial, Helvetica, sans-serif;
color: #1e1e1e;
line-height: 1.45;
@@ -290,6 +295,7 @@
}
#changeset .content a.submit {
margin-right: 4px;
+ cursor: pointer;
font: bold 12px "Helvetica Neue", HelveticaNeue, Arial, Helvetica, sans-serif;
color: #1e1e1e;
line-height: 1.45;
@@ -335,7 +341,8 @@
#changeset .content a.submit:hover span {
background-color: #fbfbfb;
}
-#changeset .content a.cancel {
+#changeset .content a.cancel, #changeset .content a.cancel-line {
+ cursor: pointer;
font: bold 12px "Helvetica Neue", HelveticaNeue, Arial, Helvetica, sans-serif;
color: #1e1e1e;
line-height: 1.45;
@@ -354,16 +361,16 @@
border-left: 1px solid #a6a6a6;
border-bottom: 1px solid #959595;
}
-#changeset .content a.cancel:active {
+#changeset .content a.cancel:active, #changeset .content a.cancel-line:active {
margin-top: 1px;
margin-bottom: -1px;
}
-#changeset .content a.cancel:focus {
+#changeset .content a.cancel:focus, #changeset .content a.cancel-line:focus {
box-shadow: 0px 0px 3px rgba(100, 100, 200, 0.9);
-moz-box-shadow: 0px 0px 3px rgba(100, 100, 200, 0.9);
-webkit-box-shadow: 0px 0px 3px rgba(100, 100, 200, 0.9);
}
-#changeset .content a.cancel span {
+#changeset .content a.cancel span, #changeset .content a.cancel-line span {
display: inline-block;
padding: 0 6px;
text-shadow: 0px 1px 1px #ffffff;
@@ -371,14 +378,14 @@
-moz-border-radius: 3px;
border-radius: 3px;
}
-#changeset .content a.cancel:hover {
+#changeset .content a.cancel:hover, #changeset .content a.cancel-line:hover {
border-top: 1px solid #d3d3d3;
border-right: 1px solid #bbbbbb;
border-left: 1px solid #bbbbbb;
border-bottom: 1px solid #a4a4a4;
background-color: #fbfbfb;
}
-#changeset .content a.cancel:hover span {
+#changeset .content a.cancel:hover span, #changeset .content a.cancel-line:hover span {
background-color: #fbfbfb;
}
#changeset .content .togglebox form {
@@ -465,10 +472,15 @@
#changeset .content .file .add-file-comment {
margin-bottom: 24px;
}
+#changeset .content .diff {
+ overflow-x: auto;
+ border: 1px solid #ddd;
+ margin-bottom: 24px;
+}
#changeset .content .diff table {
width: 100%;
- border: 1px solid #ddd;
background-color: #f9f9f9;
+ margin-bottom: 0;
}
#changeset .content .diff table td.code:after {
color: #ccc;
@@ -485,6 +497,24 @@
#changeset .content .diff table tr.viewing {
background-color: #f2f2d7;
}
+#changeset .content .diff table tr.commentable {
+ cursor: pointer;
+}
+#changeset .content .diff table tr.chosen {
+ background-color: #edecc7;
+}
+#changeset .content .diff table tr.comment-form td {
+ line-height: 15px;
+ padding: 10px 10px 15px 56px;
+ border-bottom: 1px solid #ddd;
+ border-top: 1px solid #ddd;
+ background-color: #f4f4f4;
+}
+#changeset .content .diff table tr.comment-form td textarea {
+ width: 500px;
+ height: 50px;
+ border: 1px solid #888888;
+}
#changeset .content .diff table td {
border: none;
line-height: 1;
@@ -511,8 +541,8 @@
#changeset .content .diff table td.comment {
line-height: 15px;
padding: 10px 10px 10px 56px;
- border-bottom: 1px solid #eee;
- border-top: 1px solid #eee;
+ border-bottom: 1px solid #ddd;
+ border-top: 1px solid #ddd;
background-color: #f4f4f4;
}
#changeset .content .diff table td.comment .avatar {
--- a/review/static/style.less Sun Jun 13 02:45:53 2010 -0400
+++ b/review/static/style.less Sun Jun 13 04:42:29 2010 -0400
@@ -33,6 +33,7 @@
border-bottom: 1px solid @bottom;
}
.button(@bgcolor: #ddd, @fcolor: #000000, @fsize: 14px, @lheight: 1.75) {
+ cursor: pointer;
font: bold @fsize @font-normal;
color: @bgcolor - #ccc;
line-height: @lheight;
@@ -72,6 +73,9 @@
zoom:1
}
+html {
+ overflow-y: scroll;
+}
html, body {
background-color: @c-cream;
background: @c-cream url('bg.png') top left repeat;
@@ -300,7 +304,7 @@
&:hover { .button-hover(@c-metal, #000, 12px, 1.45); }
&:hover span { .button-hover-span(@c-metal, #000, 12px, 1.45); }
}
- a.cancel {
+ a.cancel, a.cancel-line {
.button(@c-metal, #000, 12px, 1.45);
span { .button-span(@c-metal, #000, 12px, 1.45); }
&:hover { .button-hover(@c-metal, #000, 12px, 1.45); }
@@ -402,10 +406,14 @@
}
}
.diff {
- table{
+ overflow-x: auto;
+ border: 1px solid #ddd;
+ margin-bottom: 24px;
+
+ table {
width: 100%;
- border: 1px solid #ddd;
background-color: #f9f9f9;
+ margin-bottom: 0;
td.code:after {
color: #ccc;
@@ -423,6 +431,25 @@
&.viewing {
background-color: lighten(@c-cream, 5%);
}
+ &.commentable {
+ cursor: pointer;
+ }
+ &.chosen {
+ background-color: @c-cream;
+ }
+ &.comment-form td {
+ line-height: 15px;
+ padding: 10px 10px 15px 56px;
+ border-bottom: 1px solid #ddd;
+ border-top: 1px solid #ddd;
+ background-color: #f4f4f4;
+
+ textarea {
+ width: 500px;
+ height: 50px;
+ border: 1px solid @c-light;
+ }
+ }
}
td {
@@ -451,8 +478,8 @@
&.comment {
line-height: 15px;
padding: 10px 10px 10px 56px;
- border-bottom: 1px solid #eee;
- border-top: 1px solid #eee;
+ border-bottom: 1px solid #ddd;
+ border-top: 1px solid #ddd;
background-color: #f4f4f4;
.avatar {
--- a/review/templates/changeset.html Sun Jun 13 02:45:53 2010 -0400
+++ b/review/templates/changeset.html Sun Jun 13 04:42:29 2010 -0400
@@ -112,7 +112,7 @@
<h3><a class="fold" href="#">{{ filename }}</a> <span class="status">→</span> </h3>
</div>
- <div class="file-review-contents">
+ <div class="file-review-contents disabled">
{% with %}
{% set comments = rcset.file_level_comments(filename) %}
--- a/review/templates/diff.html Sun Jun 13 02:45:53 2010 -0400
+++ b/review/templates/diff.html Sun Jun 13 04:42:29 2010 -0400
@@ -1,3 +1,5 @@
+{% import 'macros.html' as macros %}
+
<div class="diff">
<table>
--- a/review/web_ui.py Sun Jun 13 02:45:53 2010 -0400
+++ b/review/web_ui.py Sun Jun 13 04:42:29 2010 -0400
@@ -94,7 +94,7 @@
filename = request.form.get('filename', '')
lines = str(request.form.get('lines', ''))
if lines:
- lines = lines.split(',')
+ lines = filter(None, [l.strip() for l in lines.split(',')])
body = request.form['new-comment-body']
if body: