gitweb: JavaScript ability to adjust time based on timezone

This patch is based on Kevin Cernekee's <cernekee@gmail.com> patch series entitled "gitweb: introduce localtime feature". While Kevin's patch changed the server side output so that the timezone was output from gitweb itself, this has a number of drawbacks, in particular with respect to gitweb-caching. This patch takes the same basic goal, display the appropriate times in a given common timezone, and implements it in JavaScript. This requires adding / using a new class, "datetime", to be able to find elements to be adjusted from JavaScript. Appropriate dates are wrapped in a span with this class. Timezone to be used can be retrieved from "gitweb_tz" cookie, though currently there is no way to set / manipulate this cookie from gitweb; this is left for later commit. Valid timezones, currently, are: "utc", "local" (which means that timezone is taken from browser), and "+/-ZZZZ" numeric timezone as in RFC-2822. Default timezone is "local" (currently not configurable, left for later commit). Fallback (should JavaScript not be enabled) is to treat dates as they have been and display them, only, in UTC. Pages affected: * 'summary' view, "last change" field (commit time from latest change) * 'log' view, author time * 'commit' and 'commitdiff' views, author/committer time * 'tag' view, tagger time Based-on-code-from: Kevin Cernekee <cernekee@gmail.com> Signed-off-by: John 'Warthog9' Hawley <warthog9@eaglescrag.net> Signed-off-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

John 'Warthog9' Hawley committed Apr 28, 2011 at 21:04 UTC 291e52bd19877dc8fdd77079ba4c4326f114c461
4 files changed +84 -3
gitweb/Makefile
+1
@@ -120,6 +120,7 @@ GITWEB_JSLIB_FILES += static/js/lib/common-lib.js
120 GITWEB_JSLIB_FILES += static/js/lib/datetime.js
121 GITWEB_JSLIB_FILES += static/js/lib/cookies.js
122 GITWEB_JSLIB_FILES += static/js/javascript-detection.js
123 +GITWEB_JSLIB_FILES += static/js/adjust-timezone.js
124 GITWEB_JSLIB_FILES += static/js/blame_incremental.js
125
126
gitweb/gitweb.perl
+8 -3
@@ -3732,9 +3732,14 @@ sub git_footer_html {
3732 qq!startBlame("!. href(action=>"blame_data", -replay=>1) .qq!",\n!.
3733 qq! "!. href() .qq!");\n!.
3734 qq!</script>\n!;
3735 - } elsif (gitweb_check_feature('javascript-actions')) {
3735 + } else {
3736 print qq!<script type="text/javascript">\n!.
3737 - qq!window.onload = fixLinks;\n!.
3737 + qq!window.onload = function () {\n!.
3738 + (gitweb_check_feature('javascript-actions') ?
3739 + qq! fixLinks();\n! : '').
3740 + # last parameter to onloadTZSetup must be CSS class used by format_timestamp_html
3741 + qq! onloadTZSetup('local', 'gitweb_tz', 'datetime');\n!.
3742 + qq!};\n!.
3743 qq!</script>\n!;
3744 }
3745
@@ -3940,7 +3945,7 @@ sub git_print_section {
3945
3946 sub format_timestamp_html {
3947 my $date = shift;
3943 - my $strtime = $date->{'rfc2822'};
3948 + my $strtime = '<span class="datetime">'.$date->{'rfc2822'}.'</span>';
3949
3950 my $localtime_format = '(%02d:%02d %s)';
3951 if ($date->{'hour_local'} < 6) {
gitweb/static/js/adjust-timezone.js new
+60
@@ -0,0 +1,60 @@
1 +// Copyright (C) 2011, John 'Warthog9' Hawley <warthog9@eaglescrag.net>
2 +// 2011, Jakub Narebski <jnareb@gmail.com>
3 +
4 +/**
5 + * @fileOverview Manipulate dates in gitweb output, adjusting timezone
6 + * @license GPLv2 or later
7 + */
8 +
9 +/**
10 + * Get common timezone and adjust dates to use this common timezone.
11 + *
12 + * This function is called during onload event (added to window.onload).
13 + *
14 + * @param {String} tzDefault: default timezone, if there is no cookie
15 + * @param {String} tzCookieName: name of cookie to store timezone
16 + * @param {String} tzClassName: denotes elements with date to be adjusted
17 + */
18 +function onloadTZSetup(tzDefault, tzCookieName, tzClassName) {
19 + var tzCookie = getCookie(tzCookieName);
20 + var tz = tzCookie ? tzCookie : tzDefault;
21 +
22 + // server-side of gitweb produces datetime in UTC,
23 + // so if tz is 'utc' there is no need for changes
24 + if (tz !== 'utc') {
25 + fixDatetimeTZ(tz, tzClassName);
26 + }
27 +}
28 +
29 +
30 +/**
31 + * Replace RFC-2822 dates contained in SPAN elements with tzClassName
32 + * CSS class with equivalent dates in given timezone.
33 + *
34 + * @param {String} tz: numeric timezone in '(-|+)HHMM' format, or 'utc', or 'local'
35 + * @param {String} tzClassName: specifies elements to be changed
36 + */
37 +function fixDatetimeTZ(tz, tzClassName) {
38 + // sanity check, method should be ensured by common-lib.js
39 + if (!document.getElementsByClassName) {
40 + return;
41 + }
42 +
43 + // translate to timezone in '(-|+)HHMM' format
44 + tz = normalizeTimezoneInfo(tz);
45 +
46 + // NOTE: result of getElementsByClassName should probably be cached
47 + var classesFound = document.getElementsByClassName(tzClassName, "span");
48 + for (var i = 0, len = classesFound.length; i < len; i++) {
49 + var curElement = classesFound[i];
50 +
51 + // we use *.firstChild.data (W3C DOM) instead of *.innerHTML
52 + // as the latter doesn't always work everywhere in every browser
53 + var epoch = parseRFC2822Date(curElement.firstChild.data);
54 + var adjusted = formatDateRFC2882(epoch, tz);
55 +
56 + curElement.firstChild.data = adjusted;
57 + }
58 +}
59 +
60 +/* end of adjust-timezone.js */
gitweb/static/js/lib/datetime.js
+15
@@ -104,6 +104,21 @@ function formatTimezoneInfo(hours, minutes, sep) {
104 return tzSign + padLeft(hours, 2, '0') + sep + padLeft(minutes, 2, '0');
105 }
106
107 +/**
108 + * translate 'utc' and 'local' to numerical timezone
109 + * @param {String} timezoneInfo: might be 'utc' or 'local' (browser)
110 + */
111 +function normalizeTimezoneInfo(timezoneInfo) {
112 + switch (timezoneInfo) {
113 + case 'utc':
114 + return '+0000';
115 + case 'local': // 'local' is browser timezone
116 + return localTimezoneInfo();
117 + }
118 + return timezoneInfo;
119 +}
120 +
121 +
122 /**
123 * return date in local time formatted in iso-8601 like format
124 * 'yyyy-mm-dd HH:MM:SS +/-ZZZZ' e.g. '2005-08-07 21:49:46 +0200'