git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Martin Koegler <mkoegler@auto.tuwien.ac.at>
To: Petr Baudis <pasky@suse.cz>
Cc: git@vger.kernel.org, Martin Koegler <mkoegler@auto.tuwien.ac.at>
Subject: [PATCH 4/5] gitweb: Selecting diffs in JavaScript
Date: Sun, 20 May 2007 22:23:31 +0200	[thread overview]
Message-ID: <11796926122089-git-send-email-mkoegler@auto.tuwien.ac.at> (raw)
In-Reply-To: <11796926121911-git-send-email-mkoegler@auto.tuwien.ac.at>

The adds support for selecting arbitrary diffs, if the client browser supports
JavaScript.

Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>
---
 Makefile           |    6 +-
 git-instaweb.sh    |    7 ++
 gitweb/gitweb.js   |  298 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gitweb/gitweb.perl |    6 +
 4 files changed, 316 insertions(+), 1 deletions(-)
 create mode 100644 gitweb/gitweb.js

diff --git a/Makefile b/Makefile
index 521c003..2d04ef9 100644
--- a/Makefile
+++ b/Makefile
@@ -167,6 +167,7 @@ GITWEB_HOMETEXT = indextext.html
 GITWEB_CSS = gitweb.css
 GITWEB_LOGO = git-logo.png
 GITWEB_FAVICON = git-favicon.png
+GITWEB_JS = gitweb.js
 GITWEB_SITE_HEADER =
 GITWEB_SITE_FOOTER =
 
@@ -811,13 +812,14 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl
 	    -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \
 	    -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \
 	    -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \
+	    -e 's|++GITWEB_JS++|$(GITWEB_JS)|g' \
 	    -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \
 	    -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g' \
 	    $< >$@+ && \
 	chmod +x $@+ && \
 	mv $@+ $@
 
-git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css
+git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css gitweb/gitweb.js
 	$(QUIET_GEN)rm -f $@ $@+ && \
 	sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
 	    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
@@ -826,6 +828,8 @@ git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css
 	    -e '/@@GITWEB_CGI@@/d' \
 	    -e '/@@GITWEB_CSS@@/r gitweb/gitweb.css' \
 	    -e '/@@GITWEB_CSS@@/d' \
+	    -e '/@@GITWEB_JS@@/r gitweb/gitweb.js' \
+	    -e '/@@GITWEB_JS@@/d' \
 	    $@.sh > $@+ && \
 	chmod +x $@+ && \
 	mv $@+ $@
diff --git a/git-instaweb.sh b/git-instaweb.sh
index cbc7418..8cb62f1 100755
--- a/git-instaweb.sh
+++ b/git-instaweb.sh
@@ -233,8 +233,15 @@ gitweb_css () {
 EOFGITWEB
 }
 
+gitweb_js () {
+	cat > "$1" <<\EOFGITWEB
+@@GITWEB_JS@@
+EOFGITWEB
+}
+
 gitweb_cgi $GIT_DIR/gitweb/gitweb.cgi
 gitweb_css $GIT_DIR/gitweb/gitweb.css
+gitweb_js $GIT_DIR/gitweb/gitweb.js
 
 case "$httpd" in
 *lighttpd*)
diff --git a/gitweb/gitweb.js b/gitweb/gitweb.js
new file mode 100644
index 0000000..cacab5a
--- /dev/null
+++ b/gitweb/gitweb.js
@@ -0,0 +1,298 @@
+/* Javascript functions for gitweb
+
+  (C) 2007 Martin Koegler <mkoegler@auto.tuwien.ac.at>
+
+  This file is licensed under the GPL v2, or (at your option) any later version.
+*/
+
+function getCookie (name)
+{
+  var name = name + "=";
+  var c = document.cookie;
+  var p = c.indexOf (name);
+  if (p == -1)
+    return null;
+  c = c.substr (p + name.length, c.length);
+  p = c.indexOf (";");
+  if (p == -1)
+    return c;
+  else
+    return c.substr (0, p);
+}
+
+function insertAfter (elem, node)
+{
+  if (node.nextSibling)
+    node.parentNode.insertBefore (elem, node.nextSibling);
+  else
+    node.parentNode.appendChild (elem);
+}
+
+function createLink (href, linktext)
+{
+  var l = document.createElement ("a");
+  l.appendChild (document.createTextNode (linktext));
+  l.href = href;
+  return l;
+}
+
+function createLinkGroup (href1, basetxt, href2, difftxt)
+{
+  var l = document.createElement ("span");
+  l.appendChild (document.createTextNode (" ("));
+  l.appendChild (createLink (href1, basetxt));
+  l.appendChild (document.createTextNode (" | "));
+  l.appendChild (createLink (href2, difftxt));
+  l.appendChild (document.createTextNode (") "));
+  return l;
+}
+
+function GitRef ()
+{
+  this.t = null;
+  this.h = null;
+  this.hb = null;
+  this.f = null;
+  this.p = null;
+  this.ToRef = ToRef;
+}
+
+function ToRef ()
+{
+  var parts = new Array ();
+  if (this.f)
+    parts.push ("f=" + this.f);
+  if (this.h)
+    parts.push ("h=" + this.h);
+  if (this.hb)
+    parts.push ("hb=" + this.hb);
+  if (this.t)
+    parts.push ("t=" + this.t);
+  if (this.p)
+    parts.push ("p=" + this.p);
+  return parts.join ("@");
+}
+
+function splitGitRef (ref)
+{
+  var parts = ref.split ("@");
+  var res = new GitRef ();
+  var i;
+  for (i = 0; i < parts.length; i++)
+    {
+      var p = parts[i].split ("=");
+      res[p[0]] = p[1];
+    }
+  return res;
+}
+
+function GitURL (base)
+{
+  this.base = base;
+  this.p = null;
+  this.a = null;
+  this.f = null;
+  this.fp = null;
+  this.h = null;
+  this.hp = null;
+  this.hb = null;
+  this.hpb = null;
+  this.pg = null;
+  this.o = null;
+  this.s = null;
+  this.st = null;
+  this.ToURL = ToURL;
+  this.ToRef = UrlToRef;
+  this.ToDUrl = ToDUrl;
+}
+
+function ToURL ()
+{
+  var parts = new Array ();
+  if (this.p)
+    parts.push ("p=" + this.p);
+  if (this.a)
+    parts.push ("a=" + this.a);
+  if (this.f)
+    parts.push ("f=" + this.f);
+  if (this.fp)
+    parts.push ("fp=" + this.fp);
+  if (this.h)
+    parts.push ("h=" + this.h);
+  if (this.hp)
+    parts.push ("hp=" + this.hp);
+  if (this.hb)
+    parts.push ("hb=" + this.hb);
+  if (this.hpb)
+    parts.push ("hpb=" + this.hpb);
+  if (this.o)
+    parts.push ("o=" + this.o);
+  if (this.s)
+    parts.push ("s=" + this.s);
+  if (this.st)
+    parts.push ("st=" + this.st);
+  return this.base + "?" + parts.join (";");
+}
+
+function UrlToRef (type)
+{
+  var res = new GitRef;
+  res.f = this.f;
+  res.h = this.h;
+  res.hb = this.hb;
+  res.t = type;
+  res.p = this.p;
+  return res.ToRef ();
+}
+
+function ToDUrl (type)
+{
+  var res = new GitURL (this.base);
+  res.f = this.f;
+  res.h = this.h;
+  res.hb = this.hb;
+  res.p = this.p;
+  res.a = type;
+  return res.ToURL ();
+}
+
+function splitGitURL (url)
+{
+  var Urls = url.split ("?");
+  var res = new GitURL (Urls[0]);
+  if (Urls.length > 1)
+    {
+      var parts = Urls[1].split (";");
+      var i;
+      for (i = 0; i < parts.length; i++)
+	{
+	  var p = parts[i].split ("=");
+	  res[p[0]] = p[1];
+	}
+    }
+  return res;
+}
+
+function base (ref)
+{
+  document.cookie = "basename=" + ref;
+}
+
+function diff (url)
+{
+  var c = getCookie ("basename");
+  if (!c)
+    {
+      alert ("no diff base selected");
+      return;
+    }
+  c = splitGitRef (c);
+  url = splitGitURL (url);
+
+  if (c.p != url.p)
+    {
+      alert ("base object in an other repository");
+      return;
+    }
+
+  if (c.t == 'commit' && url.a == 'commit')
+    {
+      url.a = 'commitdiff';
+      if (!c.h || !url.h)
+	{
+	  alert ("commit diff not possible");
+	  return;
+	}
+      url.hb = null;
+      url.f = null;
+      url.hp = c.h;
+      document.location.href = url.ToURL ();
+      return;
+    }
+  if (c.t == 'blob' && url.a == 'blob')
+    {
+      url.a = 'blobdiff';
+      url.hp = c.h;
+      url.hpb = c.hb;
+      url.fp = c.f;
+      document.location.href = url.ToURL ();
+      return;
+    }
+  if (c.t == 'tree' && url.a == 'tree')
+    {
+      url.a = 'treediff';
+      url.hpb = c.hb;
+      url.hp = c.h;
+      url.fp = c.f;
+      document.location.href = url.ToURL ();
+      return;
+    }
+  if (c.t == 'commit' && url.a == 'tree')
+    {
+      url.a = 'treediff';
+      url.hpb = c.h;
+      url.hp = null;
+      url.fp = null;
+      document.location.href = url.ToURL ();
+      return;
+    }
+  if (c.t == 'tree' && url.a == 'commit')
+    {
+      url.a = 'treediff';
+      url.hpb = c.hb;
+      url.hp = c.h;
+      url.fp = c.f;
+      url.hb = url.h;
+      url.h = null;
+      document.location.href = url.ToURL ();
+      return;
+    }
+  alert ("diff not possible");
+}
+
+function GitAddLinks ()
+{
+  var links = document.getElementsByTagName ("a");
+  var i;
+
+  for (i = 0; i < links.length; i++)
+    {
+      var link = links[i];
+      var url = splitGitURL (link.href);
+      if (link.innerHTML == 'commit' || link.innerHTML == 'tag')
+	{
+	  if (!url.h)
+	    continue;
+	  var l =
+	    createLinkGroup ("javascript:base('" + url.ToRef ('commit') +
+			     "')", "base",
+			     "javascript:diff('" + url.ToDUrl ('commit') +
+			     "')", "diff");
+	  insertAfter (l, link);
+	}
+      if (link.innerHTML == 'blob')
+	{
+	  if (!url.h && !(url.hb && url.f))
+	    continue;
+	  var l =
+	    createLinkGroup ("javascript:base('" + url.ToRef ('blob') + "')",
+			     "base",
+			     "javascript:diff('" + url.ToDUrl ('blob') + "')",
+			     "diff");
+	  insertAfter (l, link);
+	}
+      if (link.innerHTML == 'tree')
+	{
+	  if (!url.h && !(url.hb && url.f))
+	    continue;
+	  var l =
+	    createLinkGroup ("javascript:base('" + url.ToRef ('tree') + "')",
+			     "base",
+			     "javascript:diff('" + url.ToDUrl ('tree') + "')",
+			     "diff");
+	  insertAfter (l, link);
+	}
+    }
+}
+
+window.onload = GitAddLinks;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index d161c8b..f59a4b5 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -61,6 +61,8 @@ our $stylesheet = undef;
 our $logo = "++GITWEB_LOGO++";
 # URI of GIT favicon, assumed to be image/png type
 our $favicon = "++GITWEB_FAVICON++";
+# URI of gitweb.js
+our $gitwebjs = "++GITWEB_JS++";
 
 # URI and label (title) of GIT logo link
 #our $logo_url = "http://www.kernel.org/pub/software/scm/git/docs/";
@@ -1909,6 +1911,10 @@ EOF
 		print qq(<link rel="shortcut icon" href="$favicon" type="image/png"/>\n);
 	}
 
+	if (defined $gitwebjs) {
+		print qq(<script src="$gitwebjs" type="text/javascript"></script>\n);
+	}
+
 	print "</head>\n" .
 	      "<body>\n";
 
-- 
1.5.2.rc3.802.g4b4b7

  reply	other threads:[~2007-05-20 20:23 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-20 20:23 [PATCH 1/5] gitweb: Support comparing blobs with different names Martin Koegler
2007-05-20 20:23 ` [PATCH 2/5] gitweb: support filename prefix in git_patchset_body/git_difftree_body Martin Koegler
2007-05-20 20:23   ` [PATCH 3/5] gitweb: Add treediff view Martin Koegler
2007-05-20 20:23     ` Martin Koegler [this message]
2007-05-20 20:23       ` [PATCH 5/5] gitweb: Incremental blame Martin Koegler
2007-08-26  1:17       ` [PATCH 4/5] gitweb: Selecting diffs in JavaScript Petr Baudis
2007-08-26 16:17         ` Martin Koegler
2007-08-26 17:21           ` Petr Baudis
  -- strict thread matches above, loose matches on Subject: below --
2007-09-02 14:46 [PATCH 0/5] gitweb: Support for arbitrary diffs Martin Koegler
2007-09-02 14:46 ` [PATCH 1/5] gitweb: Support comparing blobs with different names Martin Koegler
2007-09-02 14:46   ` [PATCH 2/5] gitweb: support filename prefix in git_patchset_body/git_difftree_body Martin Koegler
2007-09-02 14:46     ` [PATCH 3/5] gitweb: Add treediff view Martin Koegler
2007-09-02 14:46       ` [PATCH 4/5] gitweb: Selecting diffs in JavaScript Martin Koegler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11796926122089-git-send-email-mkoegler@auto.tuwien.ac.at \
    --to=mkoegler@auto.tuwien.ac.at \
    --cc=git@vger.kernel.org \
    --cc=pasky@suse.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).