[bugzilla-gnome-org-extensions] Switch to explicit Save/Cancel buttons



commit 26b1fc5364989a1cb14bb2abf88f79d268591ba0
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Thu Sep 17 10:22:41 2009 -0400

    Switch to explicit Save/Cancel buttons
    
    Rather than making comments be saved on blur, add explicit buttons
    to Save or Cancel. Add a Delete button as well for existing comments.
    
    Code is restructured to keep the current comment in a global variable
    and identify the comment editor div as #commentEditor for easy access.
    
    Generically provide <div class='clear'/> to get clear: both.

 js/splinter.js   |  155 ++++++++++++++++++++++++++++++++++++++++--------------
 web/index.html   |    2 +-
 web/splinter.css |   35 ++++++++++++-
 3 files changed, 149 insertions(+), 43 deletions(-)
---
diff --git a/js/splinter.js b/js/splinter.js
index 4bfcf5e..8b346af 100644
--- a/js/splinter.js
+++ b/js/splinter.js
@@ -17,6 +17,8 @@ var saveDraftTimeoutId;
 var saveDraftNoticeTimeoutId;
 var savingDraft = false;
 
+var currentEditComment;
+
 const ADD_COMMENT_SUCCESS = /<title>\s*Bug[\S\s]*processed\s*<\/title>/;
 const UPDATE_ATTACHMENT_SUCCESS = /<title>\s*Changes\s+Submitted/;
 
@@ -89,6 +91,7 @@ function addComment(bug, comment, success, failure) {
 }
 
 function publishReview() {
+    saveComment();
     theReview.setIntro($("#myComment").val());
 
     var comment = "Review of attachment " + attachmentId + ":\n\n" + theReview;
@@ -126,8 +129,6 @@ function hideSaveDraftNotice() {
 }
 
 function saveDraft() {
-    theReview.setIntro($("#myComment").val());
-
     if (reviewStorage == null)
         return;
 
@@ -141,8 +142,24 @@ function saveDraft() {
     clearTimeout(saveDraftNoticeTimeoutId);
     setTimeout(hideSaveDraftNotice, 3000);
 
+    if (currentEditComment) {
+        currentEditComment.comment = Utils.strip($("#commentEditor textarea").val());
+        // Messy, we don't want the empty comment in the saved draft, so remove it and
+        // then add it back.
+        if (!currentEditComment.comment)
+            currentEditComment.remove();
+    }
+
+    theReview.setIntro($("#myComment").val());
+
     reviewStorage.saveDraft(theBug, theAttachment, theReview);
 
+    if (currentEditComment && !currentEditComment.comment) {
+        currentEditComment = currentEditComment.file.addComment(currentEditComment.location,
+                                                                currentEditComment.type,
+                                                                "");
+    }
+
     savingDraft = false;
     $("#saveDraftNotice")
         .text("Saved Draft");
@@ -215,8 +232,7 @@ function getReviewerClass(review) {
     return "reviewer-" + reviewerIndex;
 }
 
-function addCommentDisplay(row, comment) {
-    var commentArea = ensureCommentArea(row);
+function addCommentDisplay(commentArea, comment) {
     var review = comment.file.review;
 
     var separatorClass = getSeparatorClass(comment.type);
@@ -238,7 +254,9 @@ function addCommentDisplay(row, comment) {
         .addClass(getReviewerClass(review))
         .appendTo(commentArea)
         .dblclick(function() {
-                      insertCommentEditor(row, comment.type);
+                      saveComment();
+                      insertCommentEditor(commentArea,
+                                          comment.file.patchFile, comment.location, comment.type);
                   });
 
     if (review != theReview) {
@@ -252,68 +270,123 @@ function addCommentDisplay(row, comment) {
     }
 }
 
-function saveComment(row, file, location, type) {
-    var commentArea = ensureCommentArea(row);
-    var reviewFile = theReview.getFile(file.filename);
-    var comment = reviewFile.getComment(location, type);
+function saveComment() {
+    var comment = currentEditComment;
+    if (!comment)
+        return;
 
-    var value = Utils.strip($(commentArea).find("textarea").val());
-    if (value != "") {
-        if (comment)
-            comment.comment = value;
-        else
-            comment = reviewFile.addComment(location, type, value);
+    var commentEditor = $("#commentEditor").get(0);
+    var commentArea = commentEditor.parentNode;
+    var reviewFile = comment.file;
 
-        addCommentDisplay(row, comment);
+    var hunk = comment.getHunk();
+    var line = hunk.lines[comment.location - hunk.location];
+
+    var value = Utils.strip($(commentEditor).find("textarea").val());
+    if (value != "") {
+        comment.comment = value;
+        addCommentDisplay(commentArea, comment);
     } else {
-        if (comment)
-            comment.remove();
+        comment.remove();
     }
 
-    if (reviewFile.comments.length == 0) {
-        $(commentArea).parent().remove();
+    if (line.reviewComments.length > 0) {
+        $("#commentEditor").remove();
+        $("#commentEditorSeparator").remove();
     } else {
-        $(commentArea).find(".comment-editor").remove();
+        $(commentArea).parent().remove();
     }
 
+    currentEditComment = null;
     saveDraft();
 }
 
-function insertCommentEditor(clickRow, clickType) {
-    var file = $(clickRow).data('patchFile');
-    var clickLocation = $(clickRow).data('patchLocation');
+function cancelComment(previousText) {
+    $("#commentEditor textarea").val(previousText);
+    saveComment();
+}
 
-    var row = clickRow;
-    var location = clickLocation;
-    var type = clickType;
+function deleteComment() {
+    $("#commentEditor textarea").val("");
+    saveComment();
+}
+
+function insertCommentEditor(commentArea, file, location, type) {
+    saveComment();
 
     var reviewFile = theReview.getFile(file.filename);
     var comment = reviewFile.getComment(location, type);
+    if (!comment)
+        comment = reviewFile.addComment(location, type, "");
 
-    var commentArea = ensureCommentArea(row);
+    var previousText = comment.comment;
 
     var typeClass = getTypeClass(type);
     var separatorClass = getSeparatorClass(type);
 
-    if (comment) {
-        if (separatorClass)
-            $(commentArea).find(".reviewer-0." + separatorClass).remove();
-        $(commentArea).find(".reviewer-0." + typeClass).remove();
-    }
+    if (separatorClass)
+        $(commentArea).find(".reviewer-0." + separatorClass).remove();
+    $(commentArea).find(".reviewer-0." + typeClass).remove();
 
     if (separatorClass)
-        $("<div class='comment-editor'></div>")
+        $("<div class='commentEditorSeparator'></div>")
             .addClass(separatorClass)
             .appendTo(commentArea);
-    $("<div class='comment-editor'><textarea></textarea></div>")
+    $("<div id='commentEditor'>"
+      + "<div id='commentEditorInner'>"
+      + "<div id='commentTextFrame'>"
+      + "<textarea></textarea>"
+      + "</div>"
+      + "<div id='commentEditorLeftButtons'>"
+      + "<input id='commentCancel' type='button' value='Cancel' />"
+      + "</div>"
+      + "<div id='commentEditorRightButtons'>"
+      + "<input id='commentSave' type='button'value='Save' />"
+      + "</div>"
+      + "<div class='clear'></div>"
+      + "</div>"
+      + "</div>")
         .addClass(typeClass)
+        .find("#commentSave").click(saveComment).end()
+        .find("#commentCancel").click(function() {
+                                          cancelComment(previousText);
+                                      }).end()
         .appendTo(commentArea)
         .find('textarea')
-            .val(comment ? comment.comment : "")
+            .val(previousText)
+            .keypress(function(e) {
+                          if (e.which == 13 && e.ctrlKey)
+                              saveComment();
+                          else
+                              queueSaveDraft();
+                      })
+            .focus(function() {
+                       $("#commentEditor").addClass('focused');
+                   })
             .blur(function() {
-                      saveComment(row, file, location, type);
+                      $("#commentEditor").removeClass('focused');
                   })
             .each(function() { this.focus(); });
+
+    if (previousText)
+        $("<input id='commentDelete' type='button' value='Delete' />")
+            .click(deleteComment)
+            .appendTo($("#commentEditorLeftButtons"));
+
+    currentEditComment = comment;
+}
+
+function insertCommentForRow(clickRow, clickType) {
+    var file = $(clickRow).data('patchFile');
+    var clickLocation = $(clickRow).data('patchLocation');
+
+    var row = clickRow;
+    var location = clickLocation;
+    var type = clickType;
+
+    saveComment();
+    var commentArea = ensureCommentArea(row);
+    insertCommentEditor(commentArea, file, location, type);
 }
 
 function EL(element, cls, text) {
@@ -398,14 +471,16 @@ function addPatchFile(file) {
                                                 type = Patch.CHANGED;
                                             else
                                                 type = Patch.ADDED;
-                                            insertCommentEditor(this, type);
+                                            insertCommentForRow(this, type);
                                         });
 
                          tbody.appendChild(tr);
 
                          if (line.reviewComments != null)
-                             for (var k = 0; k < line.reviewComments.length; k++)
-                                 addCommentDisplay(tr, line.reviewComments[k]);
+                             for (var k = 0; k < line.reviewComments.length; k++) {
+                                 var commentArea = ensureCommentArea(tr);
+                                 addCommentDisplay(commentArea, line.reviewComments[k]);
+                             }
                      });
     }
 }
diff --git a/web/index.html b/web/index.html
index ed262f9..8317fb4 100644
--- a/web/index.html
+++ b/web/index.html
@@ -69,7 +69,7 @@
          <input id="publishButton" type="button" value="Publish" />
          <input id="cancelButton" type="button" value="Cancel" />
        </div>
-       <div id="buttonSeparator"></div>
+       <div class="clear"></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 2c366ff..b51735e 100644
--- a/web/splinter.css
+++ b/web/splinter.css
@@ -135,7 +135,7 @@ body {
     float: right;
 }
 
-#buttonSeparator {
+.clear {
     clear: both;
 }
 
@@ -229,9 +229,40 @@ body {
     font-size: 80%;
 }
 
-.comment-editor textarea {
+#commentEditor {
+    width: 50%;
+    background: #ffeeaa;
+}
+
+#commentTextFrame {
+    border: 1px solid #ffeeaa;
+    margin-bottom: 5px;
+}
+
+#commentEditor.focused #commentTextFrame {
+    border: 1px solid #8888bb;
+}
+
+#commentEditorInner {
+    margin: 0.5em;
+}
+
+#commentEditor textarea {
     width: 100%;
     height: 10em;
+    border: 0px;
+}
+
+#commentEditorLeftButtons {
+    float: left;
+}
+
+#commentEditorLeftButtons input {
+    margin-right: 0.5em;
+}
+
+#commentEditorRightButtons {
+    float: right;
 }
 
 .comment-separator-removed {


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