[bugzilla-gnome-org-extensions] Add review comment summary to the Overview page



commit f809a597487c61dca328991fdcd4d5f512c1ebf9
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Sun Oct 4 17:20:10 2009 -0400

    Add review comment summary to the Overview page
    
    Instead of just showing comments inline, show them on the overview
    page as well with context formatted similarly to the two-column
    patch display.
    
    Both old comments, and draft comments for the review are shown;
    click on an old comment jumps to that comment. Clicking on a
    draft comment jumps to it and starts editing it again.
    
    Move "Your Review" above "Previous Reviews" so that you have easy
    access to editing it when switching pages.

 js/splinter.js      |  229 +++++++++++++++++++++++++++++++++++++--------------
 web/index.html.body |   17 +++-
 web/splinter.css    |   48 +++++++++++
 3 files changed, 227 insertions(+), 67 deletions(-)
---
diff --git a/js/splinter.js b/js/splinter.js
index bde528a..5f211bb 100644
--- a/js/splinter.js
+++ b/js/splinter.js
@@ -340,6 +340,8 @@ function addCommentDisplay(commentArea, comment) {
             .find(".review-date").text(Utils.formatDate(review.date)).end()
             .appendTo(q.find(".reviewer-box"));
     }
+
+    comment.div = q.get(0);
 }
 
 function saveComment() {
@@ -513,6 +515,90 @@ function onRowDblClick(e) {
     insertCommentForRow(this, type);
 }
 
+function appendPatchTable(type, maxLine, parentDiv) {
+    var q = $("<table class='file-table'>"
+              + "</table>").appendTo(parentDiv);
+    if (type != Patch.ADDED) {
+        q.append("<col class='line-number-column'></col>");
+        q.append("<col class='old-column'></col>");
+    }
+    if (type == Patch.CHANGED) {
+        q.append("<col class='middle-column'></col>");
+    }
+    if (type != Patch.REMOVED) {
+        q.append("<col class='line-number-column'></col>");
+        q.append("<col class='new-column'></col>");
+    }
+
+    if (type == Patch.CHANGED)
+        q.addClass("file-table-changed");
+
+    if (maxLine >= 1000)
+        q.addClass("file-table-wide-numbers");
+
+    q.append("<tbody></tbody>");
+    return q.find("tbody").get(0);
+}
+
+function appendPatchHunk(file, hunk, tableType, includeComments, clickable, tbody, filter) {
+    hunk.iterate(function(loc, oldLine, oldText, newLine, newText, flags, line) {
+                     if (filter && !filter(loc))
+                         return;
+
+                     var tr = document.createElement("tr");
+
+                     var oldStyle = "";
+                     var newStyle = "";
+                     if ((flags & Patch.CHANGED) != 0)
+                         oldStyle = newStyle = "changed-line";
+                     else if ((flags & Patch.REMOVED) != 0)
+                         oldStyle = "removed-line";
+                     else if ((flags & Patch.ADDED) != 0)
+                         newStyle = "added-line";
+
+                     if (tableType != Patch.ADDED) {
+                         if (oldText != null) {
+                             tr.appendChild(EL("td", "line-number", oldLine.toString()));
+                             tr.appendChild(EL("td", "old-line " + oldStyle,
+                                               oldText != "" ? oldText : "\u00a0"));
+                             oldLine++;
+                         } else {
+                             tr.appendChild(EL("td", "line-number"));
+                             tr.appendChild(EL("td", "old-line"));
+                         }
+                     }
+
+                     if (tableType == Patch.CHANGED)
+                         tr.appendChild(EL("td", "line-middle"));
+
+                     if (tableType != Patch.REMOVED) {
+                         if (newText != null) {
+                             tr.appendChild(EL("td", "line-number", newLine.toString()));
+                             tr.appendChild(EL("td", "new-line " + newStyle,
+                                               newText != "" ? newText : "\u00a0"));
+                             newLine++;
+                         } else if (tableType == Patch.CHANGED) {
+                             tr.appendChild(EL("td", "line-number"));
+                             tr.appendChild(EL("td", "new-line"));
+                         }
+                     }
+
+                     if (clickable){
+                         $(tr).data('patchFile', file);
+                         $(tr).data('patchLocation', loc);
+                         $(tr).dblclick(onRowDblClick);
+                     }
+
+                     tbody.appendChild(tr);
+
+                     if (includeComments && line.reviewComments != null)
+                         for (var k = 0; k < line.reviewComments.length; k++) {
+                             var commentArea = ensureCommentArea(tr);
+                             addCommentDisplay(commentArea, line.reviewComments[k]);
+                         }
+                 });
+}
+
 function addPatchFile(file) {
     var fileDiv = $("<div class='file'></div>").appendTo("#files").get(0);
     file.div = fileDiv;
@@ -538,33 +624,12 @@ function addPatchFile(file) {
         .find(".file-label-status").text(statusString).end()
         .appendTo(fileDiv);
 
-    var q = $("<table class='file-table'>"
-              + "</table>").appendTo(fileDiv);
-    if (file.status != Patch.ADDED) {
-        q.append("<col class='line-number-column'></col>");
-        q.append("<col class='old-column'></col>");
-    }
-    if (file.status == Patch.CHANGED) {
-        q.append("<col class='middle-column'></col>");
-    }
-    if (file.status != Patch.REMOVED) {
-        q.append("<col class='line-number-column'></col>");
-        q.append("<col class='new-column'></col>");
-    }
-
-    if (file.status == Patch.CHANGED)
-        q.addClass("file-table-changed");
-
     var lastHunk = file.hunks[file.hunks.length -1];
     var lastLine = Math.max(lastHunk.oldStart + lastHunk.oldCount- 1,
                             lastHunk.newStart + lastHunk.newCount- 1);
 
-    if (lastLine >= 1000)
-        q.addClass("file-table-wide-numbers");
-
-    q.append("<tbody></tbody>");
+    var tbody = appendPatchTable(file.status, lastLine, fileDiv);
 
-    var tbody = q.find("tbody").get(0);
     for (var i = 0; i  < file.hunks.length; i++) {
         var hunk = file.hunks[i];
         if (hunk.oldStart > 1) {
@@ -577,56 +642,89 @@ function addPatchFile(file) {
             hunkHeader.appendChild(hunkCell);
         }
 
-        hunk.iterate(function(loc, oldLine, oldText, newLine, newText, flags, line) {
-                         var tr = document.createElement("tr");
+        appendPatchHunk(file, hunk, file.status, true, true, tbody);
+    }
+}
 
-                         var oldStyle = "";
-                         var newStyle = "";
-                         if ((flags & Patch.CHANGED) != 0)
-                             oldStyle = newStyle = "changed-line";
-                         else if ((flags & Patch.REMOVED) != 0)
-                             oldStyle = "removed-line";
-                         else if ((flags & Patch.ADDED) != 0)
-                             newStyle = "added-line";
+function appendReviewComment(comment, parentDiv) {
+    var commentDiv = EL("div", "review-patch-comment");
+    $(commentDiv).click(function() {
+                            showPatchFile(comment.file.patchFile);
+                            if (comment.file.review == theReview) {
+                                // Immediately start editing the comment again
+                                var commentArea = $(comment.div).parents(".comment-area").find("td").get(0);
+                                insertCommentEditor(commentArea,
+                                                    comment.file.patchFile, comment.location, comment.type);
+                                scrollToElement($("#commentEditor").get(0));
+                            } else {
+                                // Just scroll to the comment, don't start a reply yet
+                                scrollToElement(comment.div);
+                            }
+                        });
+
+    var inReplyTo = comment.getInReplyTo();
+    if (inReplyTo) {
+        $("<div>"
+          + "<div class='reviewer-box'>"
+          + "</div>"
+          + "</div>")
+            .addClass(getReviewerClass(inReplyTo.file.review))
+            .find(".reviewer-box").text(inReplyTo.comment).end()
+            .appendTo(commentDiv);
 
-                         if (oldText != null) {
-                             tr.appendChild(EL("td", "line-number", oldLine.toString()));
-                             tr.appendChild(EL("td", "old-line " + oldStyle,
-                                               oldText != "" ? oldText : "\u00a0"));
-                             oldLine++;
-                         } else if (file.status == Patch.CHANGED) {
-                             tr.appendChild(EL("td", "line-number"));
-                             tr.appendChild(EL("td", "old-line"));
-                         }
+        $("<div class='review-patch-comment-text'></div>")
+            .text(comment.comment)
+            .appendTo(commentDiv);
+    } else {
+        var hunk = comment.getHunk();
 
-                         if (file.status == Patch.CHANGED)
-                             tr.appendChild(EL("td", "line-middle"));
+        var lastLine = Math.max(hunk.oldStart + hunk.oldCount- 1,
+                                hunk.newStart + hunk.newCount- 1);
+        var tbody = appendPatchTable(comment.type, lastLine, commentDiv);
 
-                         if (newText != null) {
-                             tr.appendChild(EL("td", "line-number", newLine.toString()));
-                             tr.appendChild(EL("td", "new-line " + newStyle,
-                                               newText != "" ? newText : "\u00a0"));
-                             newLine++;
-                         } else if (file.status == Patch.CHANGED) {
-                             tr.appendChild(EL("td", "line-number"));
-                             tr.appendChild(EL("td", "new-line"));
-                         }
+        appendPatchHunk(comment.file.patchFile, hunk, comment.type, false, false, tbody,
+                        function(loc) {
+                            return (loc <= comment.location && comment.location - loc < 3);
+                        });
+        $("<tr>"
+          + "<td></td>"
+          + "<td class='review-patch-comment-text'></td>"
+          + "</tr>")
+            .find('.review-patch-comment-text').text(comment.comment).end()
+            .appendTo(tbody);
+    }
 
-                         $(tr).data('patchFile', file);
-                         $(tr).data('patchLocation', loc);
-                         $(tr).dblclick(onRowDblClick);
+    parentDiv.appendChild(commentDiv);
+}
+
+function appendReviewComments(review, parentDiv) {
+    for (var i = 0; i < review.files.length; i++) {
+        var file = review.files[i];
 
-                         tbody.appendChild(tr);
+        if (file.comments.length == 0)
+            continue;
+
+        parentDiv.appendChild(EL("div", "review-patch-file", file.patchFile.filename));
+        var firstComment = true;
+        for (var j = 0; j < file.comments.length; j++) {
+            if (firstComment)
+                firstComment = false;
+            else
+                parentDiv.appendChild(EL("div", "review-patch-comment-separator"));
 
-                         if (line.reviewComments != null)
-                             for (var k = 0; k < line.reviewComments.length; k++) {
-                                 var commentArea = ensureCommentArea(tr);
-                                 addCommentDisplay(commentArea, line.reviewComments[k]);
-                             }
-                     });
+            appendReviewComment(file.comments[j], parentDiv);
+        }
     }
 }
 
+function updateMyPatchComments() {
+    appendReviewComments(theReview, $("#myPatchComments").empty().get(0));
+    if ($("#myPatchComments").children().size() > 0)
+        $("#myPatchComments").show();
+    else
+        $("#myPatchComments").hide();
+}
+
 function selectNavigationLink(identifier) {
     $(".navigation-link").removeClass("navigation-link-selected");
     $(navigationLinks[identifier]).addClass("navigation-link-selected");
@@ -738,7 +836,7 @@ function start(xml) {
                 reviewers[review.who] = reviewerIndex;
             }
 
-            $("<div class='review'>"
+            var q = $("<div class='review'>"
               + "<div class='reviewer-box'>"
               + "<div class='reviewer'></div><div class='review-date'></div>"
               + "<div class='review-info-bottom'></div>"
@@ -751,6 +849,9 @@ function start(xml) {
                 .find(".review-intro").text(review.intro? review.intro : "").end()
                 .appendTo("#oldReviews");
 
+            $("#oldReviews").show();
+
+            appendReviewComments(review, q.find('.reviewer-box').get(0));
         }
     }
 
@@ -790,6 +891,8 @@ function start(xml) {
                       queueUpdateHaveDraft();
                   });
 
+    updateMyPatchComments();
+
     queueUpdateHaveDraft();
 
     $("#publishButton").click(publishReview);
diff --git a/web/index.html.body b/web/index.html.body
index 1469e3b..14c69b2 100644
--- a/web/index.html.body
+++ b/web/index.html.body
@@ -30,16 +30,20 @@
 <div id="overview" style="display: none;">
   <div id="patchIntro">
   </div>
-  <div id="oldReviews">
-  </div>
-  <div id="restored" style="display: none;">
-    Restored from draft; last edited <span id="restoredLastModified"></span>
+  <div>
+    <span class="review-title">
+      Your Review
+    </span>
+    <span id="restored" style="display: none;">
+      (Restored from draft; last edited <span id="restoredLastModified"></span>)
+    </span>
   </div>
   <div>
     <div id="myCommentFrame">
       <textarea id="myComment"></textarea>
       <div id="emptyCommentNotice">&lt;Overall Comment&gt;</div>
     </div>
+    <div id="myPatchComments"></div>
     <div id="buttonBox">
       <span id="attachmentStatusSpan">Patch Status:
        <select id="attachmentStatus"> </select>
@@ -49,6 +53,11 @@
     </div>
     <div class="clear"></div>
   </div>
+  <div id="oldReviews" style="display: none;">
+    <div class="review-title">
+      Previous Reviews
+    </div>
+  </div>
 </div>
 <div id="files" style="display: none;"></div>
 <div id="saveDraftNotice" style="display: none;"></div>
diff --git a/web/splinter.css b/web/splinter.css
index 2823bbd..1d71d99 100644
--- a/web/splinter.css
+++ b/web/splinter.css
@@ -149,6 +149,7 @@ textarea:focus {
 .review {
     border: 1px solid black;
     font-size: 90%;
+    margin-top: 0.25em;
     margin-bottom: 1em;
 }
 
@@ -156,6 +157,45 @@ textarea:focus {
     margin-top: 0.5em;
 }
 
+.review-patch-file {
+    margin-top: 0.5em;
+    font-weight: bold;
+}
+
+.review-patch-comment {
+    border: 1px solid white;
+    padding: 1px;
+    margin-top: 0.5em;
+    margin-bottom: 0.5em;
+    cursor: pointer;
+    white-space: pre-wrap;
+}
+
+.review-patch-comment:hover {
+    border: 1px solid #8888ff;
+}
+
+.review-patch-comment .file-table {
+    width: 50%;
+}
+
+.review-patch-comment .file-table-changed {
+    width: 100%;
+}
+
+.review-patch-comment-separator {
+    margin: 0.5em;
+    border-bottom: 1px solid #888888;
+}
+
+div.review-patch-comment-text {
+    margin-left: 2em;
+}
+
+.review-patch-comment .reviewer-box {
+    border-left-width: 4px;
+}
+
 #restored {
     color: #bb0000;
     margin-bottom: 0.5em;
@@ -183,7 +223,15 @@ textarea:focus {
     color: #888888;
 }
 
+#myPatchComments {
+    border: 1px solid black;
+    border-top-width: 0px;
+    padding: 0.5em;
+    font-size: 90%;
+}
+
 #buttonBox {
+    margin-top: 0.5em;
     float: right;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]