[extensions-web] Implement "diff against previous version" on the client



commit 94ad4093dadda21470cb8f6daf8eb940368a97f9
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue Nov 15 13:49:57 2011 -0500

    Implement "diff against previous version" on the client

 sweettooth/review/templates/review/review.html |    4 +
 sweettooth/review/views.py                     |   24 +++-----
 sweettooth/static/css/review.css               |   49 ++++++++++++---
 sweettooth/static/js/review-main.js            |    3 +-
 sweettooth/static/js/review.js                 |   76 ++++++++++++++++--------
 5 files changed, 104 insertions(+), 52 deletions(-)
---
diff --git a/sweettooth/review/templates/review/review.html b/sweettooth/review/templates/review/review.html
index 8f94d59..e2b298e 100644
--- a/sweettooth/review/templates/review/review.html
+++ b/sweettooth/review/templates/review/review.html
@@ -31,6 +31,10 @@
 <div id="files" data-pk="{{ version.pk }}">
 </div>
 
+<h2 class="expanded"> Diff Against Previous Version </h2>
+<div id="diff" data-pk="{{ version.pk }}">
+</div>
+
 <h2 class="expanded"> Previous Versions </h2>
 <div id="previous_versions">
   {% if previous_versions %}
diff --git a/sweettooth/review/views.py b/sweettooth/review/views.py
index df4d793..f2fefc9 100644
--- a/sweettooth/review/views.py
+++ b/sweettooth/review/views.py
@@ -111,7 +111,10 @@ def get_diff(old_zipfile, new_zipfile, filename, highlight):
     newlines = split_lines(newmarkup)
 
     old_htmls, new_htmls = get_chunks_html(oldlines, newlines)
-    return '\n'.join(old_htmls), '\n'.join(new_htmls)
+    return dict(old=dict(html='\n'.join(old_htmls),
+                         num_lines=len(oldlines)),
+                new=dict(html='\n'.join(new_htmls),
+                         num_lines=len(newlines)))
 
 @ajax_view
 @model_view(models.ExtensionVersion)
@@ -157,22 +160,11 @@ def ajax_get_file_diff_view(request, obj):
     new_filelist = set(new_zipfile.namelist())
     old_filelist = set(old_zipfile.namelist())
 
-    diff = None
-
-    if filename in old_filelist:
-        if filename in new_filelist:
-            operation = 'both'
-            diff = get_diff(old_zipfile, new_zipfile,
-                            filename, highlight)
-        else:
-            operation = 'deleted'
-    elif filename in new_filelist:
-        operation = 'added'
+    if filename in old_filelist and filename in new_filelist:
+        return get_diff(old_zipfile, new_zipfile,
+                        filename, highlight)
     else:
-        raise Http404()
-
-    return dict(operation=operation,
-                diff=diff)
+        return None
 
 @ajax_view
 @model_view(models.ExtensionVersion)
diff --git a/sweettooth/static/css/review.css b/sweettooth/static/css/review.css
index 76e847f..f0b2101 100644
--- a/sweettooth/static/css/review.css
+++ b/sweettooth/static/css/review.css
@@ -7,24 +7,24 @@
     border-top: none;
 }
 
-#files .filelist, #files table {
+.filelist, .filedisplay > table {
     box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
     margin: 0;
 }
 
-#files .filelist {
+.filelist {
     list-style-type: none;
     overflow: hidden;
     border: 1px solid #aaa;
     background-color: #EAF0F7;
 }
 
-#files .filelist li {
+.filelist li {
     margin: 0;
     margin-left: 2em;
 }
 
-#files .filelist li a {
+.filelist li a {
     float: left;
     display: block;
     padding: 0 1em;
@@ -39,7 +39,7 @@
     transition: background-color 0.2s ease-in-out, border 0.2s ease-in-out;
 }
 
-#files .filelist li a.selected {
+.filelist li a.selected {
     cursor: auto;
     color: #2e3436;
     background-color: #C8D0D5;
@@ -48,21 +48,50 @@
     border-style: none solid;
 }
 
-#files pre {
-    line-height: 1.2;
+.file pre, .filedisplay .diff, .filedisplay .filetable {
     margin: 0;
-    padding: 0.5em;
 }
 
-#files .code {
+.code {
+    white-space: pre;
+    font-family: monospace;
     padding-left: 1em;
     background-color: #fff;
+    line-height: 1.2;
+    margin: 0;
+    padding: 0.5em;
+}
+
+td.code {
+    padding: 0;
+}
+
+p.nochanges {
+    font-size: 1.4em;
 }
 
-#files .linenumbers pre {
+/* colors stolen from Splinter */
+span.deleted {
+    background-color: #ffccaa;
+}
+
+span.inserted {
+    background-color: #bbffbb;
+}
+
+span.unchanged {
+    background-color: #aaccff;
+}
+
+span.changed {
+    background-color: #cceeff;
+}
+
+.linenumbers pre {
     color: #aaa;
     text-align: right;
     background-color: #eee;
+    margin: 0;
     padding-right: 1em;
     border-right: 1px solid #ccc;
 }
diff --git a/sweettooth/static/js/review-main.js b/sweettooth/static/js/review-main.js
index 3fd5033..77c4454 100644
--- a/sweettooth/static/js/review-main.js
+++ b/sweettooth/static/js/review-main.js
@@ -2,7 +2,8 @@
 
 require(['jquery', 'main', 'review'], function($) {
     $(document).ready(function() {
-        $("#files").reviewify();
+        $("#files").reviewify(false);
+        $("#diff").reviewify(true);
         $("h2").click(function() {
             $(this).toggleClass("expanded").next().slideToggle();
         }).not(".expanded").next().hide();
diff --git a/sweettooth/static/js/review.js b/sweettooth/static/js/review.js
index 9836f78..e0cd89f 100644
--- a/sweettooth/static/js/review.js
+++ b/sweettooth/static/js/review.js
@@ -4,46 +4,72 @@ define(['jquery'], function($) {
 
     var REVIEW_URL_BASE = '/review/ajax';
 
-    function createFileView(filename, pk) {
+    function addLineNumbers(data) {
+        var $fileView, $table, $tr;
+
+        $tr = $('<tr>');
+        $table = $('<table>', {'class': 'filetable'}).append($tr);
+
+        if (data.num_lines) {
+            var count = data.num_lines;
+            var lines = [];
+            lines.push("<td class=\"linenumbers\"><pre>");
+            for (var i = 1; i < (count + 1); i ++) {
+                lines.push("<span rel=\"L" + i + "\">" + i + "</span>\n");
+            }
+            lines.push("</pre></td>");
+
+            $tr.append(lines.join(''));
+        }
+
+        $fileView = $('<div>', {'class': 'file'}).
+            appendTo($('<td>', {'width': '100%'}).appendTo($tr));
+
+        $fileView.html(data.html);
+
+        return $table;
+    }
+
+    function createFileView(filename, pk, diff) {
+        var frag = diff ? '/get-file-diff/' : '/get-file/';
+
         var req = $.ajax({
             type: 'GET',
             dataType: 'json',
             data: { filename: filename },
-            url: REVIEW_URL_BASE + '/get-file/' + pk,
+            url: REVIEW_URL_BASE + frag + pk
         });
 
         var deferred = new $.Deferred();
 
         req.done(function(data) {
-            var $fileView, $table, $tr;
-
-            $tr = $('<tr>');
-            $table = $('<table>').append($tr);
-
-            if (data.num_lines) {
-                var count = data.num_lines;
-                var lines = [];
-                lines.push("<td class=\"linenumbers\"><pre>");
-                for (var i = 1; i < (count + 1); i ++) {
-                    lines.push("<span rel=\"L" + i + "\">" + i + "</span>\n");
+            var $html;
+            if (diff) {
+                if (data === null) {
+                    $html = $('<p>', {'class': 'nochanges'}).
+                        text("There have been no changes in this file.");
+                } else {
+                    var $old = addLineNumbers(data['old']);
+                    var $new = addLineNumbers(data['new']);
+
+                    $html = $('<table>', {'class': 'diff'});
+                    var $tr = $('<tr>').appendTo($html);
+
+                    $tr.append($('<td>', {'width': '50%',
+                                          'class': 'code'}).append($old));
+                    $tr.append($('<td>', {'width': '50%',
+                                          'class': 'code'}).append($new));
                 }
-                lines.push("</pre></td>");
-
-                $tr.append(lines.join(''));
+            } else {
+                $html = addLineNumbers(data);
             }
-
-            $fileView = $('<div>', {'class': 'file'}).
-                appendTo($('<td>', {'width': '100%'}).appendTo($tr));
-
-            $fileView.html(data.html);
-
-            deferred.resolve($table);
+            deferred.resolve($html);
         });
 
         return deferred;
     }
 
-    $.fn.reviewify = function() {
+    $.fn.reviewify = function(diff) {
         var $elem = $(this);
         var $fileList = $('<ul>', {'class': 'filelist'}).appendTo($elem);
         var pk = $elem.data('pk');
@@ -96,7 +122,7 @@ define(['jquery'], function($) {
                         return;
 
                     if ($file === null) {
-                        var d = createFileView(filename, pk);
+                        var d = createFileView(filename, pk, diff);
                         currentFilename = filename;
                         d.done(function($table) {
                             $file = $table;



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