@matheusbsbs / matheus-bagliano / commits / c4ccf61f4c
Fork 0

gitweb: Create links leading to 'blame_incremental' using JavaScript

The new 'blame_incremental' view requires JavaScript to run. Not all web browsers implement JavaScript (e.g. text browsers such as Lynx), and not all users have JavaScript enabled. Therefore instead of unconditionally linking to 'blame_incremental' view, we use JavaScript to convert those links to lead to view utilizing JavaScript, by adding 'js=1' to link. Currently the only action that takes 'js=1' into account is 'blame', which then acts as if it was called as 'blame_incremental' action. Possible enhancement would be to do JavaScript redirect by setting window.location instead of modifying $format and $action in git_blame_common() subroutine. The only JavaScript-aware/using view is currently 'blame_incremental'. While at it move reading JavaScript to git_footer_html() subroutine. Note that in this view we do not add 'js=1' currently (even though perhaps we should; note that for consistency we should also add 'js=1' in links added by JavaScript part of 'blame_incremental'). This idea was originally implemented by Petr Baudis in http://article.gmane.org/gmane.comp.version-control.git/47614 but it added <script> element with fixBlameLinks() function in page header, to be added as onload event using 'onload' attribute of HTML 'body' element: <body onload="fixBlameLinks();">. This version adds script at then end of page (in the page footer), and uses JavaScript 'window.onload=fixLinks();'. Also in Petr version only links marked with 'blamelink' class were modified, and they were modified by replacing "a=blame" by "a=blame_incremental"... which doesn't work for path_info links, and might replace wrong part if there is "a=blame" in project name, ref name or file name. Slightly different solution was implemented by Martin Koegler in http://thread.gmane.org/gmane.comp.version-control.git/47902/focus=47905 Here GitAddLinks() function was in gitweb.js file, not as contents of <script> element. It was also included in page header (in <head> element) though, which means waiting for a script to load (and run). It was smarter in that to "fix" (modify) link, it split URL, modified value of 'a' parameter, and then recreated modified link. It avoids trouble with "a=blame" as substring in project name or file name, but it doesn't work with path_info URL/link in the way it was written. Signed-off-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jakub Narebski committed Sep 1, 2009 at 13:39 UTC c4ccf61f4caf8c293713586531b4a2ea709756c8
2 files changed +53 -9
gitweb/gitweb.js
+34
@@ -7,6 +7,39 @@
7 * @license GPLv2 or later
8 */
9
10 +/* ============================================================ */
11 +/* functions for generic gitweb actions and views */
12 +
13 +/**
14 + * used to check if link has 'js' query parameter already (at end),
15 + * and other reasons to not add 'js=1' param at the end of link
16 + * @constant
17 + */
18 +var jsExceptionsRe = /[;?]js=[01]$/;
19 +
20 +/**
21 + * Add '?js=1' or ';js=1' to the end of every link in the document
22 + * that doesn't have 'js' query parameter set already.
23 + *
24 + * Links with 'js=1' lead to JavaScript version of given action, if it
25 + * exists (currently there is only 'blame_incremental' for 'blame')
26 + *
27 + * @globals jsExceptionsRe
28 + */
29 +function fixLinks() {
30 + var allLinks = document.getElementsByTagName("a") || document.links;
31 + for (var i = 0, len = allLinks.length; i < len; i++) {
32 + var link = allLinks[i];
33 + if (!jsExceptionsRe.test(link)) { // =~ /[;?]js=[01]$/;
34 + link.href +=
35 + (link.href.indexOf('?') === -1 ? '?' : ';') + 'js=1';
36 + }
37 + }
38 +}
39 +
40 +
41 +/* ============================================================ */
42 +
43 /*
44 * This code uses DOM methods instead of (nonstandard) innerHTML
45 * to modify page.
@@ -89,6 +122,7 @@ function createRequestObject() {
122 return null;
123 }
124
125 +
126 /* ============================================================ */
127 /* utility/helper functions (and variables) */
128
gitweb/gitweb.perl
+19 -9
@@ -560,6 +560,8 @@ our @cgi_param_mapping = (
560 snapshot_format => "sf",
561 extra_options => "opt",
562 search_use_regexp => "sr",
563 + # this must be last entry (for manipulation from JavaScript)
564 + javascript => "js"
565 );
566 our %cgi_param_mapping = @cgi_param_mapping;
567
@@ -3242,6 +3244,18 @@ sub git_footer_html {
3244 insert_file($site_footer);
3245 }
3246
3247 + print qq!<script type="text/javascript" src="$javascript"></script>\n!;
3248 + if ($action eq 'blame_incremental') {
3249 + print qq!<script type="text/javascript">\n!.
3250 + qq!startBlame("!. href(action=>"blame_data", -replay=>1) .qq!",\n!.
3251 + qq! "!. href() .qq!");\n!.
3252 + qq!</script>\n!;
3253 + } else {
3254 + print qq!<script type="text/javascript">\n!.
3255 + qq!window.onload = fixLinks;\n!.
3256 + qq!</script>\n!;
3257 + }
3258 +
3259 print "</body>\n" .
3260 "</html>";
3261 }
@@ -4793,6 +4807,10 @@ sub git_tag {
4807
4808 sub git_blame_common {
4809 my $format = shift || 'porcelain';
4810 + if ($format eq 'porcelain' && $cgi->param('js')) {
4811 + $format = 'incremental';
4812 + $action = 'blame_incremental'; # for page title etc
4813 + }
4814
4815 # permissions
4816 gitweb_check_feature('blame')
@@ -4872,7 +4890,7 @@ sub git_blame_common {
4890 if ($format eq 'incremental') {
4891 print "<noscript>\n<div class=\"error\"><center><b>\n".
4892 "This page requires JavaScript to run.\n Use ".
4875 - $cgi->a({-href => href(action=>'blame',-replay=>1)},
4893 + $cgi->a({-href => href(action=>'blame',javascript=>0,-replay=>1)},
4894 'this page').
4895 " instead.\n".
4896 "</b></center></div>\n</noscript>\n";
@@ -5003,14 +5021,6 @@ sub git_blame_common {
5021 close $fd
5022 or print "Reading blob failed\n";
5023
5006 - if ($format eq 'incremental') {
5007 - print qq!<script type="text/javascript" src="$javascript"></script>\n!.
5008 - qq!<script type="text/javascript">\n!.
5009 - qq!startBlame("!. href(action=>"blame_data", -replay=>1) .qq!",\n!.
5010 - qq! "!. href() .qq!");\n!.
5011 - qq!</script>\n!;
5012 - }
5013 -
5024 git_footer_html();
5025 }
5026