[gitg] Transform diff json to html in a web worker
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gitg] Transform diff json to html in a web worker
- Date: Tue, 30 Oct 2012 21:22:03 +0000 (UTC)
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, '&').replace(/</g, '<').replace(/>/g, '>');
+}
+
+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]