6a6d2000c4228ad243474a69477da9eff0a1a2e4
1// Copyright (C) 2007, Fredrik Kuivinen <frekui@gmail.com>
2// 2007, Petr Baudis <pasky@suse.cz>
3// 2008-2011, Jakub Narebski <jnareb@gmail.com>
4
5/**
6 * @fileOverview Generic JavaScript code (helper functions)
7 * @license GPLv2 or later
8 */
9
10
11/* ============================================================ */
12/* ............................................................ */
13/* Padding */
14
15/**
16 * pad INPUT on the left with STR that is assumed to have visible
17 * width of single character (for example nonbreakable spaces),
18 * to WIDTH characters
19 *
20 * example: padLeftStr(12, 3, '\u00A0') == '\u00A012'
21 * ('\u00A0' is nonbreakable space)
22 *
23 * @param {Number|String} input: number to pad
24 * @param {Number} width: visible width of output
25 * @param {String} str: string to prefix to string, e.g. '\u00A0'
26 * @returns {String} INPUT prefixed with STR x (WIDTH - INPUT.length)
27 */
28function padLeftStr(input, width, str) {
29 var prefix = '';
30
31 width -= input.toString().length;
32 while (width > 0) {
33 prefix += str;
34 width--;
35 }
36 return prefix + input;
37}
38
39/**
40 * Pad INPUT on the left to WIDTH, using given padding character CH,
41 * for example padLeft('a', 3, '_') is '__a'.
42 *
43 * @param {String} input: input value converted to string.
44 * @param {Number} width: desired length of output.
45 * @param {String} ch: single character to prefix to string.
46 *
47 * @returns {String} Modified string, at least SIZE length.
48 */
49function padLeft(input, width, ch) {
50 var s = input + "";
51 while (s.length < width) {
52 s = ch + s;
53 }
54 return s;
55}
56
57
58/* ............................................................ */
59/* Ajax */
60
61/**
62 * Create XMLHttpRequest object in cross-browser way
63 * @returns XMLHttpRequest object, or null
64 */
65function createRequestObject() {
66 try {
67 return new XMLHttpRequest();
68 } catch (e) {}
69 try {
70 return window.createRequest();
71 } catch (e) {}
72 try {
73 return new ActiveXObject("Msxml2.XMLHTTP");
74 } catch (e) {}
75 try {
76 return new ActiveXObject("Microsoft.XMLHTTP");
77 } catch (e) {}
78
79 return null;
80}
81
82
83/* ............................................................ */
84/* time and data */
85
86/**
87 * used to extract hours and minutes from timezone info, e.g '-0900'
88 * @constant
89 */
90var tzRe = /^([+-])([0-9][0-9])([0-9][0-9])$/;
91
92/**
93 * convert numeric timezone +/-ZZZZ to offset from UTC in seconds
94 *
95 * @param {String} timezoneInfo: numeric timezone '(+|-)HHMM'
96 * @returns {Number} offset from UTC in seconds for timezone
97 *
98 * @globals tzRe
99 */
100function timezoneOffset(timezoneInfo) {
101 var match = tzRe.exec(timezoneInfo);
102 var tz_sign = (match[1] === '-' ? -1 : +1);
103 var tz_hour = parseInt(match[2],10);
104 var tz_min = parseInt(match[3],10);
105
106 return tz_sign*(((tz_hour*60) + tz_min)*60);
107}
108
109/**
110 * return date in local time formatted in iso-8601 like format
111 * 'yyyy-mm-dd HH:MM:SS +/-ZZZZ' e.g. '2005-08-07 21:49:46 +0200'
112 *
113 * @param {Number} epoch: seconds since '00:00:00 1970-01-01 UTC'
114 * @param {String} timezoneInfo: numeric timezone '(+|-)HHMM'
115 * @returns {String} date in local time in iso-8601 like format
116 */
117function formatDateISOLocal(epoch, timezoneInfo) {
118 // date corrected by timezone
119 var localDate = new Date(1000 * (epoch +
120 timezoneOffset(timezoneInfo)));
121 var localDateStr = // e.g. '2005-08-07'
122 localDate.getUTCFullYear() + '-' +
123 padLeft(localDate.getUTCMonth()+1, 2, '0') + '-' +
124 padLeft(localDate.getUTCDate(), 2, '0');
125 var localTimeStr = // e.g. '21:49:46'
126 padLeft(localDate.getUTCHours(), 2, '0') + ':' +
127 padLeft(localDate.getUTCMinutes(), 2, '0') + ':' +
128 padLeft(localDate.getUTCSeconds(), 2, '0');
129
130 return localDateStr + ' ' + localTimeStr + ' ' + timezoneInfo;
131}
132
133
134/* ............................................................ */
135/* unquoting/unescaping filenames */
136
137/**#@+
138 * @constant
139 */
140var escCodeRe = /\\([^0-7]|[0-7]{1,3})/g;
141var octEscRe = /^[0-7]{1,3}$/;
142var maybeQuotedRe = /^\"(.*)\"$/;
143/**#@-*/
144
145/**
146 * unquote maybe C-quoted filename (as used by git, i.e. it is
147 * in double quotes '"' if there is any escape character used)
148 * e.g. 'aa' -> 'aa', '"a\ta"' -> 'a a'
149 *
150 * @param {String} str: git-quoted string
151 * @returns {String} Unquoted and unescaped string
152 *
153 * @globals escCodeRe, octEscRe, maybeQuotedRe
154 */
155function unquote(str) {
156 function unq(seq) {
157 var es = {
158 // character escape codes, aka escape sequences (from C)
159 // replacements are to some extent JavaScript specific
160 t: "\t", // tab (HT, TAB)
161 n: "\n", // newline (NL)
162 r: "\r", // return (CR)
163 f: "\f", // form feed (FF)
164 b: "\b", // backspace (BS)
165 a: "\x07", // alarm (bell) (BEL)
166 e: "\x1B", // escape (ESC)
167 v: "\v" // vertical tab (VT)
168 };
169
170 if (seq.search(octEscRe) !== -1) {
171 // octal char sequence
172 return String.fromCharCode(parseInt(seq, 8));
173 } else if (seq in es) {
174 // C escape sequence, aka character escape code
175 return es[seq];
176 }
177 // quoted ordinary character
178 return seq;
179 }
180
181 var match = str.match(maybeQuotedRe);
182 if (match) {
183 str = match[1];
184 // perhaps str = eval('"'+str+'"'); would be enough?
185 str = str.replace(escCodeRe,
186 function (substr, p1, offset, s) { return unq(p1); });
187 }
188 return str;
189}
190
191/* end of common-lib.js */