[gitg] Updated diff styling (inspired by github)



commit 02c9d62bb64c572e58ed11c92feb99925d751bcc
Author: Jesse van den Kieboom <jessevdk gmail com>
Date:   Sat Mar 2 14:33:41 2013 +0100

    Updated diff styling (inspired by github)

 libgitg-gtk/resources/diff-view-html-builder.js |  102 +++++++++++++++----
 libgitg-gtk/resources/diff-view.css             |  125 +++++++++++++++++-----
 libgitg-gtk/resources/diff-view.html            |   10 +-
 libgitg-gtk/resources/diff-view.js              |    4 +-
 4 files changed, 183 insertions(+), 58 deletions(-)
---
diff --git a/libgitg-gtk/resources/diff-view-html-builder.js b/libgitg-gtk/resources/diff-view-html-builder.js
index 1793b27..0691032 100644
--- a/libgitg-gtk/resources/diff-view-html-builder.js
+++ b/libgitg-gtk/resources/diff-view-html-builder.js
@@ -5,10 +5,12 @@ function html_escape(s)
 
 function diff_file(file, lnstate, data)
 {
-       var f = '<div>';
-
        tabrepl = '<span class="tab" style="width: ' + data.settings.tab_width + 'ex">\t</span>';
 
+       var tablecontent = '';
+       var added = 0;
+       var removed = 0;
+
        for (var i = 0; i < file.hunks.length; ++i)
        {
                var h = file.hunks[i];
@@ -16,7 +18,13 @@ function diff_file(file, lnstate, data)
                var cold = h.range.old.start;
                var cnew = h.range.new.start;
 
-               var tablecontent = '';
+               var hunkheader = '@@ -' + h.range.old.start + ',' + h.range.old.lines + ' +' + 
h.range.new.start + ',' + h.range.new.lines + ' @@';
+
+               tablecontent += '<tr class="hunk_header">\
+                       <td class="gutter old">' + lnstate.gutterdots + '</td> \
+                       <td class="gutter new">' + lnstate.gutterdots + '</td> \
+                       <td class="hunk_header">' + hunkheader + '</td> \
+               </tr>';
 
                for (var j = 0; j < h.lines.length; ++j)
                {
@@ -28,20 +36,28 @@ function diff_file(file, lnstate, data)
                        switch (o)
                        {
                                case ' ':
-                                       row += 'context"><td>' + cold + '</td><td>' + cnew + '</td>';
+                                       row += 'context"> \
+                                               <td class="gutter old">' + cold + '</td> \
+                                               <td class="gutter new">' + cnew + '</td>';
 
                                        cold++;
                                        cnew++;
                                break;
                                case '+':
-                                       row += 'added"><td></td><td>' + cnew + '</td>';
+                                       row += 'added"> \
+                                               <td class="gutter old"></td> \
+                                               <td class="gutter new">' + cnew + '</td>';
 
                                        cnew++;
+                                       added++;
                                break;
                                case '-':
-                                       row += 'removed"><td>' + cold + '</td><td></td>';
+                                       row += 'removed"> \
+                                               <td class="gutter old">' + cold + '</td> \
+                                               <td class="gutter new"></td>';
 
                                        cold++;
+                                       removed++;
                                break;
                                default:
                                        row += '">';
@@ -65,29 +81,68 @@ function diff_file(file, lnstate, data)
                                }
                        }
                }
+       }
 
-               var filepath;
+       var filepath;
 
-               if (file.file.new.path)
-               {
-                       filepath = file.file.new.path;
-               }
-               else
-               {
-                       filepath = file.file.old.path;
-               }
+       if (file.file.new.path)
+       {
+               filepath = file.file.new.path;
+       }
+       else
+       {
+               filepath = file.file.old.path;
+       }
+
+       var total = added + removed;
+       var addedp = Math.floor(added / total * 100);
+       var removedp = 100 - addedp;
 
-               var template = data.hunk_template.replace('<!-- ${FILEPATH} -->', filepath);
-               f += template.replace('<!-- ${TABLE_BODY} -->', tablecontent);
+       var stats = '<div class="stats"><span class="number">' + (added + removed)  + '</span><span 
class="bar"><span class="added" style="width: ' + addedp + '%;"></span><span class="removed" style="width: ' 
+ removedp + '%;"></span></span></div>';
+
+       var template = data.file_template;
+       var repls = {
+               'FILEPATH': filepath,
+               'TABLE_BODY': tablecontent,
+               'STATS': stats,
+       };
+
+       for (var r in repls)
+       {
+               log([template, lnstate.replacements[r], repls[r]]);
+               template = template.replace(lnstate.replacements[r], repls[r]);
        }
 
-       return f + '</div>';
+       return template;
 }
 
-function diff_files(files, lines, data)
+function diff_files(files, lines, maxlines, data)
 {
        var f = '';
-       lnstate = {lines: lines, processed: 0, nexttick: 0, tickfreq: 0.01};
+
+       var repl = [
+               'FILEPATH',
+               'GUTTER_DOTS',
+               'TABLE_BODY',
+               'STATS'
+       ];
+
+       var replacements = {};
+
+       for (var r in repl)
+       {
+               replacements[repl[r]] = new RegExp('<!-- \\$\\{' + repl[r] + '\\} -->', 'g');
+       }
+
+       var lnstate = {
+               lines: lines,
+               maxlines: maxlines,
+               gutterdots: new Array(maxlines.toString().length + 1).join('.'),
+               processed: 0,
+               nexttick: 0,
+               tickfreq: 0.01,
+               replacements: replacements,
+       };
 
        for (var i = 0; i < files.length; ++i)
        {
@@ -97,6 +152,11 @@ function diff_files(files, lines, data)
        return f;
 }
 
+function log(e)
+{
+       self.postMessage({'log': e});
+}
+
 self.onmessage = function(event) {
        var data = event.data;
 
@@ -105,7 +165,7 @@ self.onmessage = function(event) {
 
        r.onload = function(e) {
                var j = JSON.parse(r.responseText);
-               var html = diff_files(j.diff, j.lines, data);
+               var html = diff_files(j.diff, j.lines, j.maxlines, data);
 
                self.postMessage({url: data.url, diff_html: html});
        }
diff --git a/libgitg-gtk/resources/diff-view.css b/libgitg-gtk/resources/diff-view.css
index 4d1c08f..c15b2c3 100644
--- a/libgitg-gtk/resources/diff-view.css
+++ b/libgitg-gtk/resources/diff-view.css
@@ -12,14 +12,13 @@ div#diff {
   -webkit-tab-size: 4;
 }
 
-div#diff div.hunk {
+div#diff div.file {
   overflow: auto;
 }
 
-div#diff div.hunk table {
+div#diff div.file table {
   border-collapse: collapse;
   width: 100%;
-  border-bottom: 1px solid #d3d7cf;
 }
 
 img.avatar {
@@ -47,7 +46,15 @@ div.commit div.message {
   margin-bottom: 15px;
 }
 
-div#diff div.hunk table td {
+div#diff div.file table .gutter {
+  padding-left: 6px;
+  padding-right: 6px;
+  background-color: #ececec;
+  color: #aaa;
+  text-align: right;
+}
+
+div#diff div.file table td {
   white-space: pre;
 }
 
@@ -56,49 +63,109 @@ span.tab {
   display: inline-block;
 }
 
-div#diff div.hunk table.wrapped td {
+div#diff div.file table.wrapped td {
   white-space: pre-wrap;
 }
 
-div#diff div.hunk table tr.added td:last-child {
-  background-color: #ccffcc;
+div#diff div.file table.contents {
+  margin-top: 50px;
 }
 
-div#diff div.hunk table tr.removed td:last-child {
-  background-color: #ffcccc;
+div#diff div.file:first-child table.contents {
+  margin-top: 0px;
 }
 
-div#diff div.hunk table thead th {
-  background-color: #eeeeec;
-  padding-top: 3px;
-  padding-bottom: 3px;
+div#diff div.file table tr.context td:last-child {
+  background-color: #fafafa;
 }
 
-div#diff div.hunk table thead th.filepath {
-  text-align: left;
-  padding-left: 5px;
-  font-family: sans-serif;
+
+div#diff div.file table tr.added td:last-child {
+  background-color: #ddffdd;
 }
 
-div#diff div.hunk table td {
-  vertical-align: top;
+div#diff div.file table tr.removed td:last-child {
+  background-color: #ffdddd;
 }
 
-div#diff div.hunk div#diff div.hunk table td:nth-child(0), div#diff div.hunk div#diff div.hunk table 
td:nth-child(1) {
-  padding-right: 2px;
-  padding-left: 2px;
-  background-color: #eeeeec;
-  text-align: right;
-  color: #888a85;
+div#diff div.file table tr.hunk_header td {
+  padding-top: 6px;
+  padding-bottom: 6px;
 }
 
-div#diff div.hunk table th.gutter {
-  text-align: center;
+div.file tr.file_header td {
+  border-bottom: 1px solid #ccc;
+  text-shadow: 1px 1px #fff;
+}
+
+div.file:first-child table.contents tr.file_header td {
+  background: -webkit-gradient(linear, left top, left bottom, from(#d3d7cf), to(#eeeeec));
+}
+
+div.stats {
+  width: 75px;
+  background-color: #ececec;
+  padding: 6px;
+  border-radius: 5px;
+  box-shadow: 1px 1px #ccc inset;
+  margin: 10px;
+  display: inline-block;
+  vertical-align: middle;
+}
+
+div.stats .number, div.stats .bar {
+  display: table-cell;
+  vertical-align: middle;
+}
+
+div.stats .bar {
+  width: 100%;
+  padding: 0px 0px 0px 6px;
 }
 
-div#diff div.hunk table td:nth-child(2), div#diff div.hunk table th:nth-child(2)  {
+div.stats .added, div.stats .removed {
+  height: 5px;
+  float: left;
+  display: block;
+}
+
+div.stats .added {
+  background-color: #33cc33;
+}
+
+div.stats .removed {
+  background-color: #cc3333;
+}
+
+div#diff div.file table tr.file_header td {
+  vertical-align: middle;
+}
+
+div#diff div.file table tr.file_header + tr.hunk_header td.hunk_header {
+  border-top: 0px;
+}
+
+div#diff div.file table td.hunk_header {
+  color: #aaa;
+  background-color: #ececec;
+  border-top: 1px solid #d3d7cf;
+  border-bottom: 1px solid #d3d7cf;
+}
+
+div#diff div.file table td {
+  vertical-align: top;
+}
+
+div#diff div.file table td.gutter.new {
   border-right: 3px solid #d3d7cf;
-  border-left: 1px solid #d3d7cf;
+}
+
+div#diff div.file table tr.hunk_header td.gutter.new {
+  border: 0;
+}
+
+div#diff div.file table td.gutter.old {
+  border-right: 1px solid #d3d7cf;
 }
 
 div.commit {
diff --git a/libgitg-gtk/resources/diff-view.html b/libgitg-gtk/resources/diff-view.html
index a7c0708..b337e2b 100644
--- a/libgitg-gtk/resources/diff-view.html
+++ b/libgitg-gtk/resources/diff-view.html
@@ -19,19 +19,17 @@
       </div>
 
       <!-- Hunk template -->
-      <div class="hunk">
+      <div class="file">
         <table class="contents">
           <colgroup>
             <col width="0">
             <col width="0">
             <col width="100%">
           </colgroup>
-          <thead>
-            <th class="gutter">-</th>
-            <th class="gutter">+</th>
-            <th class="filepath"><!-- ${FILEPATH} --></th>
-          </thead>
           <tbody>
+            <tr class="file_header">
+              <td colspan="3"><!-- ${STATS} --><!-- ${FILEPATH} --></td>
+            </tr>
             <!-- ${TABLE_BODY} -->
           </tbody>
         </table>
diff --git a/libgitg-gtk/resources/diff-view.js b/libgitg-gtk/resources/diff-view.js
index 4bf0d81..85c40b7 100644
--- a/libgitg-gtk/resources/diff-view.js
+++ b/libgitg-gtk/resources/diff-view.js
@@ -174,13 +174,13 @@ function update_diff(id)
 
        var t = (new Date()).getTime();
 
-       var hunk_template = $('#templates div.hunk')[0].outerHTML;
+       var file_template = $('#templates div.file')[0].outerHTML;
 
        // Load the diff asynchronously
        html_builder_worker.postMessage({
                url: "gitg-diff:/diff/?t=" + t + "&viewid=" + params.viewid + "&diffid=" + id + 
"&format=diff_only",
                settings: settings,
-               hunk_template: hunk_template,
+               file_template: file_template,
        });
 
        // Load the commit directly here


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