{"thread":{"id":"26865","subject":"[PATCH/RFC 0/3] gitweb: Split gitweb.js, improve JavaScript","startedAt":"2011-03-25T21:46:23Z","lastAt":"2011-03-26T11:08:42Z","messageCount":6,"participants":["Jakub Narebski","J.H."],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"164330","messageId":"1301089586-8534-1-git-send-email-jnareb@gmail.com","threadId":"26865","inReplyTo":null,"subject":"[PATCH/RFC 0/3] gitweb: Split gitweb.js, improve JavaScript","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-03-25T21:46:23Z","receivedAt":"2011-03-25T21:46:23Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"This patch series is inspired by patch by John 'Warthog9' Hawley\n\n  [PATCH 1/1] gitweb: javascript ability to adjust time based on timezone\n  Message-Id: <1300925335-3212-2-git-send-email-warthog9@eaglescrag.net>\n  http://thread.gmane.org/gmane.comp.version-control.git/169384/focus=169882\n\nthat added a few new JavaScript files for the new feature that this\npatch implemented.\n\nThis is marked as RFC mainly because other patches in series,\nespecially the last one fixing bug in gitweb's JavaScript code, should\nbe send independently on gitweb.js splitting.\n\nJakub Narebski (3):\n  gitweb: Split JavaScript for maintability; concatenate on build\n  gitweb: Update and improve comments in JavaScript files\n  gitweb: Fix parsing of negative fractional timezones in JavaScript\n\n .gitignore                                         |    1 +\n gitweb/Makefile                                    |   12 +-\n .../static/{gitweb.js => js/blame_incremental.js}  |  216 ++------------------\n gitweb/static/js/common-lib.js                     |  191 +++++++++++++++++\n gitweb/static/js/detect-javascript.js              |   44 ++++\n 5 files changed, 261 insertions(+), 203 deletions(-)\n rename gitweb/static/{gitweb.js => js/blame_incremental.js} (75%)\n create mode 100644 gitweb/static/js/common-lib.js\n create mode 100644 gitweb/static/js/detect-javascript.js\n\n-- \n1.7.3\n"},{"id":"164332","messageId":"1301089586-8534-2-git-send-email-jnareb@gmail.com","threadId":"26865","inReplyTo":"1301089586-8534-1-git-send-email-jnareb@gmail.com","subject":"[PATCH/RFC 1/3] gitweb: Split JavaScript for maintability; concatenate on build","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-03-25T21:46:24Z","receivedAt":"2011-03-25T21:46:24Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Split single gitweb.js file into smaller files, each dealing with\nsingle thing.  This should make gitweb's JavaScript code easier to\nmaintain.\n\nFor better webapp performance it is recommended[1][2][3] to combine\nJavaScript files.  Do it during build time (in gitweb/Makefile), by\nstraight concatenation of files into gitweb.js file (which is now\nignored as being generated).  This means that there are no changes to\ngitweb script itself - it still uses gitweb.js or gitweb.min.js, but\nnow generated.\n\n[1]: http://developer.yahoo.com/performance/rules.html\n     \"Minimize HTTP Requests\" section\n[2]: http://code.google.com/speed/articles/include-scripts-properly.html\n     \"1. Combine external JavaScript files\"\n[3]: http://javascript-reference.info/speed-up-your-javascript-load-time.htm\n     \"Combine Your Files\" section.\n\nInspired-by-patch-by: John 'Warthog9' Hawley <warthog9@eaglescrag.net>\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n .gitignore                                         |    1 +\n gitweb/Makefile                                    |   12 +-\n .../static/{gitweb.js => js/blame_incremental.js}  |  196 +-------------------\n gitweb/static/js/common-lib.js                     |  173 +++++++++++++++++\n gitweb/static/js/detect-javascript.js              |   44 +++++\n 5 files changed, 233 insertions(+), 193 deletions(-)\n rename gitweb/static/{gitweb.js => js/blame_incremental.js} (77%)\n create mode 100644 gitweb/static/js/common-lib.js\n create mode 100644 gitweb/static/js/detect-javascript.js\n\ndiff --git a/.gitignore b/.gitignore\nindex c460c66..601c71a 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -160,6 +160,7 @@\n /gitk-git/gitk-wish\n /gitweb/GITWEB-BUILD-OPTIONS\n /gitweb/gitweb.cgi\n+/gitweb/static/gitweb.js\n /gitweb/static/gitweb.min.*\n /test-chmtime\n /test-ctype\ndiff --git a/gitweb/Makefile b/gitweb/Makefile\nindex 0a6ac00..230b1b9 100644\n--- a/gitweb/Makefile\n+++ b/gitweb/Makefile\n@@ -86,7 +86,7 @@ ifndef V\n endif\n endif\n \n-all:: gitweb.cgi\n+all:: gitweb.cgi static/gitweb.js\n \n GITWEB_PROGRAMS = gitweb.cgi\n \n@@ -112,6 +112,11 @@ endif\n \n GITWEB_FILES += static/git-logo.png static/git-favicon.png\n \n+GITWEB_JSLIB_FILES += static/js/common-lib.js\n+GITWEB_JSLIB_FILES += static/js/detect-javascript.js\n+GITWEB_JSLIB_FILES += static/js/blame_incremental.js\n+\n+\n GITWEB_REPLACE = \\\n \t-e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \\\n \t-e 's|++GIT_BINDIR++|$(bindir)|g' \\\n@@ -146,6 +151,11 @@ gitweb.cgi: gitweb.perl GITWEB-BUILD-OPTIONS\n \tchmod +x $@+ && \\\n \tmv $@+ $@\n \n+static/gitweb.js: $(GITWEB_JSLIB_FILES)\n+\t$(QUIET_GEN)$(RM) $@ $@+ && \\\n+\tcat $^ >$@+ && \\\n+\tmv $@+ $@\n+\n ### Testing rules\n \n test:\ndiff --git a/gitweb/static/gitweb.js b/gitweb/static/js/blame_incremental.js\nsimilarity index 77%\nrename from gitweb/static/gitweb.js\nrename to gitweb/static/js/blame_incremental.js\nindex 9c66928..3317390 100644\n--- a/gitweb/static/gitweb.js\n+++ b/gitweb/static/js/blame_incremental.js\n@@ -1,44 +1,13 @@\n // Copyright (C) 2007, Fredrik Kuivinen <frekui@gmail.com>\n //               2007, Petr Baudis <pasky@suse.cz>\n-//          2008-2009, Jakub Narebski <jnareb@gmail.com>\n+//          2008-2011, Jakub Narebski <jnareb@gmail.com>\n \n /**\n- * @fileOverview JavaScript code for gitweb (git web interface).\n+ * @fileOverview JavaScript side of Ajax-y 'blame_incremental' view in gitweb\n+ *               requires functions in common-lib.js to be available\n  * @license GPLv2 or later\n  */\n \n-/* ============================================================ */\n-/* functions for generic gitweb actions and views */\n-\n-/**\n- * used to check if link has 'js' query parameter already (at end),\n- * and other reasons to not add 'js=1' param at the end of link\n- * @constant\n- */\n-var jsExceptionsRe = /[;?]js=[01]$/;\n-\n-/**\n- * Add '?js=1' or ';js=1' to the end of every link in the document\n- * that doesn't have 'js' query parameter set already.\n- *\n- * Links with 'js=1' lead to JavaScript version of given action, if it\n- * exists (currently there is only 'blame_incremental' for 'blame')\n- *\n- * @globals jsExceptionsRe\n- */\n-function fixLinks() {\n-\tvar allLinks = document.getElementsByTagName(\"a\") || document.links;\n-\tfor (var i = 0, len = allLinks.length; i < len; i++) {\n-\t\tvar link = allLinks[i];\n-\t\tif (!jsExceptionsRe.test(link)) { // =~ /[;?]js=[01]$/;\n-\t\t\tlink.href +=\n-\t\t\t\t(link.href.indexOf('?') === -1 ? '?' : ';') + 'js=1';\n-\t\t}\n-\t}\n-}\n-\n-\n-/* ============================================================ */\n \n /*\n  * This code uses DOM methods instead of (nonstandard) innerHTML\n@@ -59,71 +28,6 @@ function fixLinks() {\n \n \n /* ============================================================ */\n-/* generic utility functions */\n-\n-\n-/**\n- * pad number N with nonbreakable spaces on the left, to WIDTH characters\n- * example: padLeftStr(12, 3, '\\u00A0') == '\\u00A012'\n- *          ('\\u00A0' is nonbreakable space)\n- *\n- * @param {Number|String} input: number to pad\n- * @param {Number} width: visible width of output\n- * @param {String} str: string to prefix to string, e.g. '\\u00A0'\n- * @returns {String} INPUT prefixed with (WIDTH - INPUT.length) x STR\n- */\n-function padLeftStr(input, width, str) {\n-\tvar prefix = '';\n-\n-\twidth -= input.toString().length;\n-\twhile (width > 0) {\n-\t\tprefix += str;\n-\t\twidth--;\n-\t}\n-\treturn prefix + input;\n-}\n-\n-/**\n- * Pad INPUT on the left to SIZE width, using given padding character CH,\n- * for example padLeft('a', 3, '_') is '__a'.\n- *\n- * @param {String} input: input value converted to string.\n- * @param {Number} width: desired length of output.\n- * @param {String} ch: single character to prefix to string.\n- *\n- * @returns {String} Modified string, at least SIZE length.\n- */\n-function padLeft(input, width, ch) {\n-\tvar s = input + \"\";\n-\twhile (s.length < width) {\n-\t\ts = ch + s;\n-\t}\n-\treturn s;\n-}\n-\n-/**\n- * Create XMLHttpRequest object in cross-browser way\n- * @returns XMLHttpRequest object, or null\n- */\n-function createRequestObject() {\n-\ttry {\n-\t\treturn new XMLHttpRequest();\n-\t} catch (e) {}\n-\ttry {\n-\t\treturn window.createRequest();\n-\t} catch (e) {}\n-\ttry {\n-\t\treturn new ActiveXObject(\"Msxml2.XMLHTTP\");\n-\t} catch (e) {}\n-\ttry {\n-\t\treturn new ActiveXObject(\"Microsoft.XMLHTTP\");\n-\t} catch (e) {}\n-\n-\treturn null;\n-}\n-\n-\n-/* ============================================================ */\n /* utility/helper functions (and variables) */\n \n var xhr;        // XMLHttpRequest object\n@@ -392,98 +296,6 @@ function fixColorsAndGroups() {\n \t}\n }\n \n-/* ............................................................ */\n-/* time and data */\n-\n-/**\n- * used to extract hours and minutes from timezone info, e.g '-0900'\n- * @constant\n- */\n-var tzRe = /^([+-][0-9][0-9])([0-9][0-9])$/;\n-\n-/**\n- * return date in local time formatted in iso-8601 like format\n- * 'yyyy-mm-dd HH:MM:SS +/-ZZZZ' e.g. '2005-08-07 21:49:46 +0200'\n- *\n- * @param {Number} epoch: seconds since '00:00:00 1970-01-01 UTC'\n- * @param {String} timezoneInfo: numeric timezone '(+|-)HHMM'\n- * @returns {String} date in local time in iso-8601 like format\n- *\n- * @globals tzRe\n- */\n-function formatDateISOLocal(epoch, timezoneInfo) {\n-\tvar match = tzRe.exec(timezoneInfo);\n-\t// date corrected by timezone\n-\tvar localDate = new Date(1000 * (epoch +\n-\t\t(parseInt(match[1],10)*3600 + parseInt(match[2],10)*60)));\n-\tvar localDateStr = // e.g. '2005-08-07'\n-\t\tlocalDate.getUTCFullYear()                 + '-' +\n-\t\tpadLeft(localDate.getUTCMonth()+1, 2, '0') + '-' +\n-\t\tpadLeft(localDate.getUTCDate(),    2, '0');\n-\tvar localTimeStr = // e.g. '21:49:46'\n-\t\tpadLeft(localDate.getUTCHours(),   2, '0') + ':' +\n-\t\tpadLeft(localDate.getUTCMinutes(), 2, '0') + ':' +\n-\t\tpadLeft(localDate.getUTCSeconds(), 2, '0');\n-\n-\treturn localDateStr + ' ' + localTimeStr + ' ' + timezoneInfo;\n-}\n-\n-/* ............................................................ */\n-/* unquoting/unescaping filenames */\n-\n-/**#@+\n- * @constant\n- */\n-var escCodeRe = /\\\\([^0-7]|[0-7]{1,3})/g;\n-var octEscRe = /^[0-7]{1,3}$/;\n-var maybeQuotedRe = /^\\\"(.*)\\\"$/;\n-/**#@-*/\n-\n-/**\n- * unquote maybe git-quoted filename\n- * e.g. 'aa' -> 'aa', '\"a\\ta\"' -> 'a\ta'\n- *\n- * @param {String} str: git-quoted string\n- * @returns {String} Unquoted and unescaped string\n- *\n- * @globals escCodeRe, octEscRe, maybeQuotedRe\n- */\n-function unquote(str) {\n-\tfunction unq(seq) {\n-\t\tvar es = {\n-\t\t\t// character escape codes, aka escape sequences (from C)\n-\t\t\t// replacements are to some extent JavaScript specific\n-\t\t\tt: \"\\t\",   // tab            (HT, TAB)\n-\t\t\tn: \"\\n\",   // newline        (NL)\n-\t\t\tr: \"\\r\",   // return         (CR)\n-\t\t\tf: \"\\f\",   // form feed      (FF)\n-\t\t\tb: \"\\b\",   // backspace      (BS)\n-\t\t\ta: \"\\x07\", // alarm (bell)   (BEL)\n-\t\t\te: \"\\x1B\", // escape         (ESC)\n-\t\t\tv: \"\\v\"    // vertical tab   (VT)\n-\t\t};\n-\n-\t\tif (seq.search(octEscRe) !== -1) {\n-\t\t\t// octal char sequence\n-\t\t\treturn String.fromCharCode(parseInt(seq, 8));\n-\t\t} else if (seq in es) {\n-\t\t\t// C escape sequence, aka character escape code\n-\t\t\treturn es[seq];\n-\t\t}\n-\t\t// quoted ordinary character\n-\t\treturn seq;\n-\t}\n-\n-\tvar match = str.match(maybeQuotedRe);\n-\tif (match) {\n-\t\tstr = match[1];\n-\t\t// perhaps str = eval('\"'+str+'\"'); would be enough?\n-\t\tstr = str.replace(escCodeRe,\n-\t\t\tfunction (substr, p1, offset, s) { return unq(p1); });\n-\t}\n-\treturn str;\n-}\n-\n /* ============================================================ */\n /* main part: parsing response */\n \n@@ -872,4 +684,4 @@ function startBlame(blamedataUrl, bUrl) {\n \tpollTimer = setInterval(xhr.onreadystatechange, 1000);\n }\n \n-// end of gitweb.js\n+/* end of blame_incremental.js */\ndiff --git a/gitweb/static/js/common-lib.js b/gitweb/static/js/common-lib.js\nnew file mode 100644\nindex 0000000..566c98a\n--- /dev/null\n+++ b/gitweb/static/js/common-lib.js\n@@ -0,0 +1,173 @@\n+// Copyright (C) 2007, Fredrik Kuivinen <frekui@gmail.com>\n+//               2007, Petr Baudis <pasky@suse.cz>\n+//          2008-2011, Jakub Narebski <jnareb@gmail.com>\n+\n+/**\n+ * @fileOverview Generic JavaScript code (helper functions).\n+ * @license GPLv2 or later\n+ */\n+\n+\n+/* ============================================================ */\n+/* ............................................................ */\n+/* Padding */\n+\n+/**\n+ * pad number N with nonbreakable spaces on the left, to WIDTH characters\n+ * example: padLeftStr(12, 3, '\\u00A0') == '\\u00A012'\n+ *          ('\\u00A0' is nonbreakable space)\n+ *\n+ * @param {Number|String} input: number to pad\n+ * @param {Number} width: visible width of output\n+ * @param {String} str: string to prefix to string, e.g. '\\u00A0'\n+ * @returns {String} INPUT prefixed with (WIDTH - INPUT.length) x STR\n+ */\n+function padLeftStr(input, width, str) {\n+\tvar prefix = '';\n+\n+\twidth -= input.toString().length;\n+\twhile (width > 0) {\n+\t\tprefix += str;\n+\t\twidth--;\n+\t}\n+\treturn prefix + input;\n+}\n+\n+/**\n+ * Pad INPUT on the left to SIZE width, using given padding character CH,\n+ * for example padLeft('a', 3, '_') is '__a'.\n+ *\n+ * @param {String} input: input value converted to string.\n+ * @param {Number} width: desired length of output.\n+ * @param {String} ch: single character to prefix to string.\n+ *\n+ * @returns {String} Modified string, at least SIZE length.\n+ */\n+function padLeft(input, width, ch) {\n+\tvar s = input + \"\";\n+\twhile (s.length < width) {\n+\t\ts = ch + s;\n+\t}\n+\treturn s;\n+}\n+\n+\n+/* ............................................................ */\n+/* Ajax */\n+\n+/**\n+ * Create XMLHttpRequest object in cross-browser way\n+ * @returns XMLHttpRequest object, or null\n+ */\n+function createRequestObject() {\n+\ttry {\n+\t\treturn new XMLHttpRequest();\n+\t} catch (e) {}\n+\ttry {\n+\t\treturn window.createRequest();\n+\t} catch (e) {}\n+\ttry {\n+\t\treturn new ActiveXObject(\"Msxml2.XMLHTTP\");\n+\t} catch (e) {}\n+\ttry {\n+\t\treturn new ActiveXObject(\"Microsoft.XMLHTTP\");\n+\t} catch (e) {}\n+\n+\treturn null;\n+}\n+\n+\n+/* ............................................................ */\n+/* time and data */\n+\n+/**\n+ * used to extract hours and minutes from timezone info, e.g '-0900'\n+ * @constant\n+ */\n+var tzRe = /^([+-][0-9][0-9])([0-9][0-9])$/;\n+\n+/**\n+ * return date in local time formatted in iso-8601 like format\n+ * 'yyyy-mm-dd HH:MM:SS +/-ZZZZ' e.g. '2005-08-07 21:49:46 +0200'\n+ *\n+ * @param {Number} epoch: seconds since '00:00:00 1970-01-01 UTC'\n+ * @param {String} timezoneInfo: numeric timezone '(+|-)HHMM'\n+ * @returns {String} date in local time in iso-8601 like format\n+ *\n+ * @globals tzRe\n+ */\n+function formatDateISOLocal(epoch, timezoneInfo) {\n+\tvar match = tzRe.exec(timezoneInfo);\n+\t// date corrected by timezone\n+\tvar localDate = new Date(1000 * (epoch +\n+\t\t(parseInt(match[1],10)*3600 + parseInt(match[2],10)*60)));\n+\tvar localDateStr = // e.g. '2005-08-07'\n+\t\tlocalDate.getUTCFullYear()                 + '-' +\n+\t\tpadLeft(localDate.getUTCMonth()+1, 2, '0') + '-' +\n+\t\tpadLeft(localDate.getUTCDate(),    2, '0');\n+\tvar localTimeStr = // e.g. '21:49:46'\n+\t\tpadLeft(localDate.getUTCHours(),   2, '0') + ':' +\n+\t\tpadLeft(localDate.getUTCMinutes(), 2, '0') + ':' +\n+\t\tpadLeft(localDate.getUTCSeconds(), 2, '0');\n+\n+\treturn localDateStr + ' ' + localTimeStr + ' ' + timezoneInfo;\n+}\n+\n+\n+/* ............................................................ */\n+/* unquoting/unescaping filenames */\n+\n+/**#@+\n+ * @constant\n+ */\n+var escCodeRe = /\\\\([^0-7]|[0-7]{1,3})/g;\n+var octEscRe = /^[0-7]{1,3}$/;\n+var maybeQuotedRe = /^\\\"(.*)\\\"$/;\n+/**#@-*/\n+\n+/**\n+ * unquote maybe git-quoted filename\n+ * e.g. 'aa' -> 'aa', '\"a\\ta\"' -> 'a\ta'\n+ *\n+ * @param {String} str: git-quoted string\n+ * @returns {String} Unquoted and unescaped string\n+ *\n+ * @globals escCodeRe, octEscRe, maybeQuotedRe\n+ */\n+function unquote(str) {\n+\tfunction unq(seq) {\n+\t\tvar es = {\n+\t\t\t// character escape codes, aka escape sequences (from C)\n+\t\t\t// replacements are to some extent JavaScript specific\n+\t\t\tt: \"\\t\",   // tab            (HT, TAB)\n+\t\t\tn: \"\\n\",   // newline        (NL)\n+\t\t\tr: \"\\r\",   // return         (CR)\n+\t\t\tf: \"\\f\",   // form feed      (FF)\n+\t\t\tb: \"\\b\",   // backspace      (BS)\n+\t\t\ta: \"\\x07\", // alarm (bell)   (BEL)\n+\t\t\te: \"\\x1B\", // escape         (ESC)\n+\t\t\tv: \"\\v\"    // vertical tab   (VT)\n+\t\t};\n+\n+\t\tif (seq.search(octEscRe) !== -1) {\n+\t\t\t// octal char sequence\n+\t\t\treturn String.fromCharCode(parseInt(seq, 8));\n+\t\t} else if (seq in es) {\n+\t\t\t// C escape sequence, aka character escape code\n+\t\t\treturn es[seq];\n+\t\t}\n+\t\t// quoted ordinary character\n+\t\treturn seq;\n+\t}\n+\n+\tvar match = str.match(maybeQuotedRe);\n+\tif (match) {\n+\t\tstr = match[1];\n+\t\t// perhaps str = eval('\"'+str+'\"'); would be enough?\n+\t\tstr = str.replace(escCodeRe,\n+\t\t\tfunction (substr, p1, offset, s) { return unq(p1); });\n+\t}\n+\treturn str;\n+}\n+\n+/* end of common-lib.js */\ndiff --git a/gitweb/static/js/detect-javascript.js b/gitweb/static/js/detect-javascript.js\nnew file mode 100644\nindex 0000000..12a221d\n--- /dev/null\n+++ b/gitweb/static/js/detect-javascript.js\n@@ -0,0 +1,44 @@\n+// Copyright (C) 2007, Fredrik Kuivinen <frekui@gmail.com>\n+//               2007, Petr Baudis <pasky@suse.cz>\n+//          2008-2011, Jakub Narebski <jnareb@gmail.com>\n+\n+/**\n+ * @fileOverview Detect if JavaScript is enabled, and pass it to server-side,\n+ *               so that JavaScript-only version of page would/could be used\n+ * @license GPLv2 or later\n+ */\n+\n+\n+/* ============================================================ */\n+/* Manipulating links */\n+\n+/**\n+ * used to check if link has 'js' query parameter already (at end),\n+ * and other reasons to not add 'js=1' param at the end of link\n+ * @constant\n+ */\n+var jsExceptionsRe = /[;?]js=[01]$/;\n+\n+/**\n+ * Add '?js=1' or ';js=1' to the end of every link in the document\n+ * that doesn't have 'js' query parameter set already.\n+ *\n+ * Links with 'js=1' lead to JavaScript version of given action, if it\n+ * exists (currently there is only 'blame_incremental' for 'blame')\n+ *\n+ * To be used as `window.onload` handler\n+ *\n+ * @globals jsExceptionsRe\n+ */\n+function fixLinks() {\n+\tvar allLinks = document.getElementsByTagName(\"a\") || document.links;\n+\tfor (var i = 0, len = allLinks.length; i < len; i++) {\n+\t\tvar link = allLinks[i];\n+\t\tif (!jsExceptionsRe.test(link)) { // =~ /[;?]js=[01]$/;\n+\t\t\tlink.href +=\n+\t\t\t\t(link.href.indexOf('?') === -1 ? '?' : ';') + 'js=1';\n+\t\t}\n+\t}\n+}\n+\n+/* end of detect-javascript.js */\n-- \n1.7.3\n"},{"id":"164331","messageId":"1301089586-8534-3-git-send-email-jnareb@gmail.com","threadId":"26865","inReplyTo":"1301089586-8534-1-git-send-email-jnareb@gmail.com","subject":"[PATCH/RFC 2/3] gitweb: Update and improve comments in JavaScript files","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-03-25T21:46:25Z","receivedAt":"2011-03-25T21:46:25Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Spell 'neighbor' using American spelling (and not 'neighbour').\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/static/js/blame_incremental.js |   22 +++++++++++-----------\n gitweb/static/js/common-lib.js        |   12 ++++++++----\n 2 files changed, 19 insertions(+), 15 deletions(-)\n\ndiff --git a/gitweb/static/js/blame_incremental.js b/gitweb/static/js/blame_incremental.js\nindex 3317390..2067dcd 100644\n--- a/gitweb/static/js/blame_incremental.js\n+++ b/gitweb/static/js/blame_incremental.js\n@@ -8,7 +8,7 @@\n  * @license GPLv2 or later\n  */\n \n-\n+/* ============================================================ */\n /*\n  * This code uses DOM methods instead of (nonstandard) innerHTML\n  * to modify page.\n@@ -27,7 +27,7 @@\n  */\n \n \n-/* ============================================================ */\n+/* ............................................................ */\n /* utility/helper functions (and variables) */\n \n var xhr;        // XMLHttpRequest object\n@@ -133,7 +133,7 @@ function writeTimeInterval() {\n }\n \n /**\n- * show an error message alert to user within page (in prohress info area)\n+ * show an error message alert to user within page (in progress info area)\n  * @param {String} str: plain text error message (no HTML)\n  *\n  * @globals div_progress_info\n@@ -183,7 +183,7 @@ function getColorNo(tr) {\n \n var colorsFreq = [0, 0, 0];\n /**\n- * return one of given possible colors (curently least used one)\n+ * return one of given possible colors (currently least used one)\n  * example: chooseColorNoFrom(2, 3) returns 2 or 3\n  *\n  * @param {Number[]} arguments: one or more numbers\n@@ -204,8 +204,8 @@ function chooseColorNoFrom() {\n }\n \n /**\n- * given two neigbour <tr> elements, find color which would be different\n- * from color of both of neighbours; used to 3-color blame table\n+ * given two neighbor <tr> elements, find color which would be different\n+ * from color of both of neighbors; used to 3-color blame table\n  *\n  * @param {HTMLElement} tr_prev\n  * @param {HTMLElement} tr_next\n@@ -217,14 +217,14 @@ function findColorNo(tr_prev, tr_next) {\n \tvar color_next = getColorNo(tr_next);\n \n \n-\t// neither of neighbours has color set\n+\t// neither of neighbors has color set\n \t// THEN we can use any of 3 possible colors\n \tif (!color_prev && !color_next) {\n \t\treturn chooseColorNoFrom(1,2,3);\n \t}\n \n-\t// either both neighbours have the same color,\n-\t// or only one of neighbours have color set\n+\t// either both neighbors have the same color,\n+\t// or only one of neighbors have color set\n \t// THEN we can use any color except given\n \tvar color;\n \tif (color_prev === color_next) {\n@@ -238,7 +238,7 @@ function findColorNo(tr_prev, tr_next) {\n \t\treturn chooseColorNoFrom((color % 3) + 1, ((color+1) % 3) + 1);\n \t}\n \n-\t// neighbours have different colors\n+\t// neighbors have different colors\n \t// THEN there is only one color left\n \treturn (3 - ((color_prev + color_next) % 3));\n }\n@@ -259,7 +259,7 @@ function isStartOfGroup(tr) {\n \n /**\n  * change colors to use zebra coloring (2 colors) instead of 3 colors\n- * concatenate neighbour commit groups belonging to the same commit\n+ * concatenate neighbor commit groups belonging to the same commit\n  *\n  * @globals colorRe\n  */\ndiff --git a/gitweb/static/js/common-lib.js b/gitweb/static/js/common-lib.js\nindex 566c98a..33887d7 100644\n--- a/gitweb/static/js/common-lib.js\n+++ b/gitweb/static/js/common-lib.js\n@@ -13,14 +13,17 @@\n /* Padding */\n \n /**\n- * pad number N with nonbreakable spaces on the left, to WIDTH characters\n+ * pad INPUT on the left with STR that is assumed to have visible\n+ * width of single character (for example nonbreakable spaces),\n+ * to WIDTH characters\n+ *\n  * example: padLeftStr(12, 3, '\\u00A0') == '\\u00A012'\n  *          ('\\u00A0' is nonbreakable space)\n  *\n  * @param {Number|String} input: number to pad\n  * @param {Number} width: visible width of output\n  * @param {String} str: string to prefix to string, e.g. '\\u00A0'\n- * @returns {String} INPUT prefixed with (WIDTH - INPUT.length) x STR\n+ * @returns {String} INPUT prefixed with STR x (WIDTH - INPUT.length)\n  */\n function padLeftStr(input, width, str) {\n \tvar prefix = '';\n@@ -34,7 +37,7 @@ function padLeftStr(input, width, str) {\n }\n \n /**\n- * Pad INPUT on the left to SIZE width, using given padding character CH,\n+ * Pad INPUT on the left to WIDTH, using given padding character CH,\n  * for example padLeft('a', 3, '_') is '__a'.\n  *\n  * @param {String} input: input value converted to string.\n@@ -126,7 +129,8 @@ var maybeQuotedRe = /^\\\"(.*)\\\"$/;\n /**#@-*/\n \n /**\n- * unquote maybe git-quoted filename\n+ * unquote maybe C-quoted filename (as used by git, i.e. it is\n+ * in double quotes '\"' if there is any escape character used)\n  * e.g. 'aa' -> 'aa', '\"a\\ta\"' -> 'a\ta'\n  *\n  * @param {String} str: git-quoted string\n-- \n1.7.3\n"},{"id":"164333","messageId":"1301089586-8534-4-git-send-email-jnareb@gmail.com","threadId":"26865","inReplyTo":"1301089586-8534-1-git-send-email-jnareb@gmail.com","subject":"[PATCH/RFC 3/3] gitweb: Fix parsing of negative fractional timezones in JavaScript","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-03-25T21:46:26Z","receivedAt":"2011-03-25T21:46:26Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Extract converting numerical timezone in the form of '(+|-)HHMM' to\ntimezoneOffset function, and fix parsing of negative fractional\ntimezones.\n\nThis was used to format timestamps in 'blame_incremental' view.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/static/js/common-lib.js |   24 +++++++++++++++++++-----\n 1 files changed, 19 insertions(+), 5 deletions(-)\n\ndiff --git a/gitweb/static/js/common-lib.js b/gitweb/static/js/common-lib.js\nindex 33887d7..cc72d1e 100644\n--- a/gitweb/static/js/common-lib.js\n+++ b/gitweb/static/js/common-lib.js\n@@ -87,7 +87,24 @@ function createRequestObject() {\n  * used to extract hours and minutes from timezone info, e.g '-0900'\n  * @constant\n  */\n-var tzRe = /^([+-][0-9][0-9])([0-9][0-9])$/;\n+var tzRe = /^([-+])([0-9][0-9])([0-9][0-9])$/;\n+\n+/**\n+ * convert numeric timezone +/-ZZZZ to offset from UTC in seconds\n+ *\n+ * @param {String} timezoneInfo: numeric timezone '(+|-)HHMM'\n+ * @returns {Number} offset from UTC in seconds for timezone\n+ *\n+ * @globals tzRe\n+ */\n+function timezoneOffset(timezoneInfo) {\n+\tvar match = tzRe.exec(timezoneInfo);\n+\tvar tz_sign = (match[1] === '-' ? -1 : +1);\n+\tvar tz_hour = parseInt(match[2],10);\n+\tvar tz_min  = parseInt(match[3],10);\n+\n+\treturn tz_sign*(((tz_hour*60) + tz_min)*60);\n+}\n \n /**\n  * return date in local time formatted in iso-8601 like format\n@@ -96,14 +113,11 @@ var tzRe = /^([+-][0-9][0-9])([0-9][0-9])$/;\n  * @param {Number} epoch: seconds since '00:00:00 1970-01-01 UTC'\n  * @param {String} timezoneInfo: numeric timezone '(+|-)HHMM'\n  * @returns {String} date in local time in iso-8601 like format\n- *\n- * @globals tzRe\n  */\n function formatDateISOLocal(epoch, timezoneInfo) {\n-\tvar match = tzRe.exec(timezoneInfo);\n \t// date corrected by timezone\n \tvar localDate = new Date(1000 * (epoch +\n-\t\t(parseInt(match[1],10)*3600 + parseInt(match[2],10)*60)));\n+\t\ttimezoneOffset(timezoneInfo)));\n \tvar localDateStr = // e.g. '2005-08-07'\n \t\tlocalDate.getUTCFullYear()                 + '-' +\n \t\tpadLeft(localDate.getUTCMonth()+1, 2, '0') + '-' +\n-- \n1.7.3\n"},{"id":"164335","messageId":"4D8D112A.5020703@eaglescrag.net","threadId":"26865","inReplyTo":"1301089586-8534-1-git-send-email-jnareb@gmail.com","subject":"Re: [PATCH/RFC 0/3] gitweb: Split gitweb.js, improve JavaScript","fromName":"J.H.","fromEmail":"warthog9@eaglescrag.net","sentAt":"2011-03-25T22:03:22Z","receivedAt":"2011-03-25T22:03:22Z","isPatch":true,"sender":{"key":"warthog9@kernel.org","avatar":"https://avatars.githubusercontent.com/u/2334704?v=4"},"body":"The only thing I would comment on is that we may want to document (for\nthe build process) a way to force a certain ordering of various files.\nCase in point we probably want to force the things like various global\ndefs (what I'm proposing in the timezone stuff) at the top and let the\nfunction defs go below that.\n\nOther than that this all looks good.\n\n- John 'Warthog9' Hawley\n\nOn 03/25/2011 02:46 PM, Jakub Narebski wrote:\n> This patch series is inspired by patch by John 'Warthog9' Hawley\n> \n>   [PATCH 1/1] gitweb: javascript ability to adjust time based on timezone\n>   Message-Id: <1300925335-3212-2-git-send-email-warthog9@eaglescrag.net>\n>   http://thread.gmane.org/gmane.comp.version-control.git/169384/focus=169882\n> \n> that added a few new JavaScript files for the new feature that this\n> patch implemented.\n> \n> This is marked as RFC mainly because other patches in series,\n> especially the last one fixing bug in gitweb's JavaScript code, should\n> be send independently on gitweb.js splitting.\n> \n> Jakub Narebski (3):\n>   gitweb: Split JavaScript for maintability; concatenate on build\n>   gitweb: Update and improve comments in JavaScript files\n>   gitweb: Fix parsing of negative fractional timezones in JavaScript\n> \n>  .gitignore                                         |    1 +\n>  gitweb/Makefile                                    |   12 +-\n>  .../static/{gitweb.js => js/blame_incremental.js}  |  216 ++------------------\n>  gitweb/static/js/common-lib.js                     |  191 +++++++++++++++++\n>  gitweb/static/js/detect-javascript.js              |   44 ++++\n>  5 files changed, 261 insertions(+), 203 deletions(-)\n>  rename gitweb/static/{gitweb.js => js/blame_incremental.js} (75%)\n>  create mode 100644 gitweb/static/js/common-lib.js\n>  create mode 100644 gitweb/static/js/detect-javascript.js\n> \n"},{"id":"164359","messageId":"201103261208.44548.jnareb@gmail.com","threadId":"26865","inReplyTo":"4D8D112A.5020703@eaglescrag.net","subject":"Re: [PATCH/RFC 0/3] gitweb: Split gitweb.js, improve JavaScript","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-03-26T11:08:42Z","receivedAt":"2011-03-26T11:08:42Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Fri, 25 Mar 2011, J.H. wrote:\n\n> The only thing I would comment on is that we may want to document (for\n> the build process) a way to force a certain ordering of various files.\n> Case in point we probably want to force the things like various global\n> defs (what I'm proposing in the timezone stuff) at the top and let the\n> function defs go below that.\n \nActually I don't think that matters, at least not if JavaScript files\ncontain only variables and functions, and do not include any code that\nis actually run when file is loaded.  A very simple test (below) \nconfirms that.\n\nIn JavaScript variable declarations ('var' keyword) and function \ndefinitions ('function' keyword) get \"hoisted\" at beginning.  \n\n> Other than that this all looks good.\n\nThanks.\n \n-- 8< --\n<html>\n<head>\n<title>JavaScript test</title>\n<script>\n// -------------------------------------------\n// B\n\nvar varB = 'varB';\n\nfunction fooB() {\n  fooA();\n  alert('varB='+varB + '; varA='+varA);\n  return 'fooB';\n}\n\n\n// -------------------------------------------\n// A\n\nvar varA = 'varA';\n\nfunction fooA() {\n  alert('varA='+varA);\n  return 'fooA';\n}\n\n\n// ===========================================\n// main\nfooB();\n</script>\n</head>\n<body>\ntest\n</body>\n</html>\n-- >8 --\n-- \nJakub Narebski\nPoland\n"}]}