[gitg] Transform diff json to html in a web worker



commit 9f77f189238975a3ce8f8b5fd26d831124420f2c
Author: Jesse van den Kieboom <jessevdk gnome org>
Date:   Tue Oct 30 22:21:41 2012 +0100

    Transform diff json to html in a web worker

 libgitg-gtk/resources/diff-view-html-builder.js    |  115 ++++++++++++++++
 libgitg-gtk/resources/{base.css => diff-view.css}  |   12 ++
 .../resources/{base.html => diff-view.html}        |    9 +-
 libgitg-gtk/resources/{base.js => diff-view.js}    |  138 +++++++-------------
 libgitg-gtk/resources/resources.xml                |    7 +-
 5 files changed, 187 insertions(+), 94 deletions(-)
---
diff --git a/libgitg-gtk/resources/diff-view-html-builder.js b/libgitg-gtk/resources/diff-view-html-builder.js
new file mode 100644
index 0000000..a187c88
--- /dev/null
+++ b/libgitg-gtk/resources/diff-view-html-builder.js
@@ -0,0 +1,115 @@
+function html_escape(s)
+{
+	return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+}
+
+function diff_file(file, lnstate, data)
+{
+	var f = '<div>';
+
+	tabrepl = '<span class="tab" style="width: ' + data.settings.tab_width + 'ex">\t</span>';
+
+	for (var i = 0; i < file.hunks.length; ++i)
+	{
+		var h = file.hunks[i];
+
+		var cold = h.range.old.start;
+		var cnew = h.range.new.start;
+
+		var tablecontent = '';
+
+		for (var j = 0; j < h.lines.length; ++j)
+		{
+			var l = h.lines[j];
+			var o = String.fromCharCode(l.type);
+
+			var row = '<tr class="';
+
+			switch (o)
+			{
+				case ' ':
+					row += 'context"><td>' + cold + '</td><td>' + cnew + '</td>';
+
+					cold++;
+					cnew++;
+				break;
+				case '+':
+					row += 'added"><td></td><td>' + cnew + '</td>';
+
+					cnew++;
+				break;
+				case '-':
+					row += 'removed"><td>' + cold + '</td><td></td>';
+
+					cold++;
+				break;
+				default:
+					row += '">';
+				break;
+			}
+
+			row += '<td>' + html_escape(l.content).replace(/\t/g, tabrepl) + '</td>';
+			tablecontent += row;
+
+			lnstate.processed++;
+
+			proc = lnstate.lines / lnstate.processed;
+
+			if (proc >= lnstate.nexttick)
+			{
+				self.postMessage({tick: proc});
+
+				while (proc >= lnstate.nexttick)
+				{
+					lnstate.nexttick += lnstate.tickfreq;
+				}
+			}
+		}
+
+		var filepath;
+
+		if (file.file.new.path)
+		{
+			filepath = file.file.new.path;
+		}
+		else
+		{
+			filepath = file.file.old.path;
+		}
+
+		var template = data.hunk_template.replace('<!-- ${FILEPATH} -->', filepath);
+		f += template.replace('<!-- ${TABLE_BODY} -->', tablecontent);
+	}
+
+	return f + '</div>';
+}
+
+function diff_files(files, lines, data)
+{
+	var f = '';
+	lnstate = {lines: lines, processed: 0, nexttick: 0, tickfreq: 0.01};
+
+	for (var i = 0; i < files.length; ++i)
+	{
+		f += diff_file(files[i], lnstate, data);
+	}
+
+	return f;
+}
+
+self.onmessage = function(event) {
+	var data = event.data;
+
+	// Make request to get the diff formatted in json
+	var r = new XMLHttpRequest();
+
+	r.onload = function(e) {
+		var j = JSON.parse(r.responseText);
+		var html = diff_files(j.diff, j.lines, data);
+
+		self.postMessage({url: data.url, diff_html: html});
+	}
+
+	r.open("GET", data.url);
+	r.send();
+};
diff --git a/libgitg-gtk/resources/base.css b/libgitg-gtk/resources/diff-view.css
similarity index 88%
rename from libgitg-gtk/resources/base.css
rename to libgitg-gtk/resources/diff-view.css
index 92b8bb0..4d1c08f 100644
--- a/libgitg-gtk/resources/base.css
+++ b/libgitg-gtk/resources/diff-view.css
@@ -124,4 +124,16 @@ a {
   color: #3465a4;
 }
 
+div.loading {
+  margin: 30px;
+  border: 1px solid #d3d7cf;
+  background: -webkit-gradient(linear, left top, left bottom, from(#eeeeec), to(#d3d7cf));
+  font-size: 1.2em;
+  font-weight: bold;
+  color: #333;
+  text-align: center;
+  padding: 30px;
+  font-family: sans-serif;
+}
+
 /* vi:ts=2:et */
diff --git a/libgitg-gtk/resources/base.html b/libgitg-gtk/resources/diff-view.html
similarity index 75%
rename from libgitg-gtk/resources/base.html
rename to libgitg-gtk/resources/diff-view.html
index c31868c..a7c0708 100644
--- a/libgitg-gtk/resources/base.html
+++ b/libgitg-gtk/resources/diff-view.html
@@ -1,9 +1,9 @@
 <!DOCTYPE>
 <html>
   <head>
-    <link rel="stylesheet" href="base.css" type="text/css" media="screen" charset="utf-8" />
+    <link rel="stylesheet" href="diff-view.css" type="text/css" media="screen" charset="utf-8" />
     <script type="text/javascript" src="jquery-1.7.2.min.js"></script>
-    <script type="text/javascript" src="base.js"></script>
+    <script type="text/javascript" src="diff-view.js"></script>
   </head>
   <body>
     <div id="templates">
@@ -29,8 +29,11 @@
           <thead>
             <th class="gutter">-</th>
             <th class="gutter">+</th>
-            <th class="filepath"></th>
+            <th class="filepath"><!-- ${FILEPATH} --></th>
           </thead>
+          <tbody>
+            <!-- ${TABLE_BODY} -->
+          </tbody>
         </table>
       </div>
     </div>
diff --git a/libgitg-gtk/resources/base.js b/libgitg-gtk/resources/diff-view.js
similarity index 70%
rename from libgitg-gtk/resources/base.js
rename to libgitg-gtk/resources/diff-view.js
index 86365de..4822505 100644
--- a/libgitg-gtk/resources/base.js
+++ b/libgitg-gtk/resources/diff-view.js
@@ -106,111 +106,88 @@ function html_escape(str)
 	return escapeDiv.innerHTML;
 }
 
-function diff_file(file)
+
+function write_commit(commit)
 {
-	var f = '<div>';
+	return run_template('commit', commit);
+}
 
-	tabrepl = '<span class="tab" style="width: ' + settings.tab_width + 'ex">\t</span>';
+var html_builder_worker = 0;
+var html_builder_tick = 0;
 
-	for (var i = 0; i < file.hunks.length; ++i)
+function update_diff()
+{
+	if (html_builder_worker)
 	{
-		var h = file.hunks[i];
-		var ht = run_template('hunk', {file: file, hunk: h});
+		html_builder_worker.terminate();
+	}
+
+	html_builder_worker = new Worker('diff-view-html-builder.js');
+	html_builder_tick = 0;
+
+	var content = document.getElementById('diff_content');
 
-		var table = ht.children('table');
+	html_builder_progress_timeout = setTimeout(function (){
+		var eta = 200 / html_builder_tick - 200;
 
-		if (settings.wrap)
+		if (eta > 1000)
 		{
-			table.addClass('wrapped');
+			// Show the progress
+			content.innerHTML = '<div class="loading">Loading diff...</div>.';
 		}
 
-		var cold = h.range.old.start;
-		var cnew = h.range.new.start;
+		html_builder_progress_timeout = 0;
+	}, 200);
 
-		var tablecontent = '';
-
-		for (var j = 0; j < h.lines.length; ++j)
+	html_builder_worker.onmessage = function (event) {
+		if (event.data.log)
 		{
-			var l = h.lines[j];
-			var o = String.fromCharCode(l.type);
-
-			var row = '<tr class="';
+			console.log(event.data.log);
+		}
+		else if (event.data.tick)
+		{
+			html_builder_tick = event.data.tick;
+		}
+		else
+		{
+			html_builder_worker.terminate();
+			html_builder_worker = 0;
 
-			switch (o)
+			if (html_builder_progress_timeout)
 			{
-				case ' ':
-					row += 'context"><td>' + cold + '</td><td>' + cnew + '</td>';
-
-					cold++;
-					cnew++;
-				break;
-				case '+':
-					row += 'added"><td></td><td>' + cnew + '</td>';
-
-					cnew++;
-				break;
-				case '-':
-					row += 'removed"><td>' + cold + '</td><td></td>';
-
-					cold++;
-				break;
-				default:
-					row += '">';
-				break;
+				clearTimeout(html_builder_progress_timeout);
+				html_builder_progress_timeout = 0;
 			}
 
-			row += '<td>' + html_escape(l.content).replace(/\t/g, tabrepl) + '</td>';
-			tablecontent += row;
+			content.innerHTML = event.data.diff_html;
 		}
-
-		var h = ht[0].outerHTML;
-		var findstr = '</table>';
-		var idx = h.indexOf(findstr);
-
-		f += h.substring(0, idx) + tablecontent + h.substring(idx);
 	}
 
-	return f + '</div>';
-}
-
-function write_diff(res)
-{
-	var f = '';
-
-	for (var i = 0; i < res.length; ++i)
-	{
-		f += diff_file(res[i]);
-	}
+	var t = (new Date()).getTime();
 
-	return f;
-}
+	var hunk_template = $('#templates div.hunk')[0].outerHTML;
 
-function write_commit(commit)
-{
-	return run_template('commit', commit);
-}
+	// Load the diff asynchronously
+	html_builder_worker.postMessage({
+		url: "gitg-diff:/diff/?t=" + t + "&viewid=" + params.viewid + "&format=diff_only",
+		settings: settings,
+		hunk_template: hunk_template,
+	});
 
-function update_diff()
-{
+	// Load the commit directly here
 	var r = new XMLHttpRequest();
 
 	r.onload = function(e) {
 		var j = JSON.parse(r.responseText);
 
-		var html = '';
-
 		if ('commit' in j)
 		{
 			$('#diff_header').html(write_commit(j.commit));
 		}
-
-		var content = document.getElementById('diff_content');
-		content.innerHTML = write_diff(j.diff);
 	}
 
-	var t = (new Date()).getTime();
-
-	r.open("GET", "gitg-diff:/diff/?t=" + t + "&viewid=" + params.viewid);
+	t = (new Date()).getTime();
+	r.open("GET", "gitg-diff:/diff/?t=" + t + "&viewid=" + params.viewid + "&format=commit_only");
 	r.send();
 }
 
@@ -256,21 +233,6 @@ function date_to_string(d)
 }
 
 addEventListener('DOMContentLoaded', function () {
-	create_template("hunk", {
-		'.filepath': function () {
-			var f = this.file.file;
-
-			if (f.new.path)
-			{
-				return f.new.path;
-			}
-			else
-			{
-				return f.old.path;
-			}
-		},
-	});
-
 	create_template("commit", {
 		'.author': function () {
 			var name = $('<span/>', {'class': 'author name'}).text(this.author.name);
diff --git a/libgitg-gtk/resources/resources.xml b/libgitg-gtk/resources/resources.xml
index c996367..37454f2 100644
--- a/libgitg-gtk/resources/resources.xml
+++ b/libgitg-gtk/resources/resources.xml
@@ -1,9 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gresources>
   <gresource prefix="/org/gnome/gitg/gtk/diff-view">
-    <file compressed="true">base.html</file>
-    <file compressed="true">base.js</file>
-    <file compressed="true">base.css</file>
+    <file compressed="true">diff-view.html</file>
+    <file compressed="true">diff-view.js</file>
+    <file compressed="true">diff-view-html-builder.js</file>
+    <file compressed="true">diff-view.css</file>
     <file compressed="true">jquery-1.7.2.min.js</file>
   </gresource>
 </gresources>



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