Cleanup JS (based on JSLint advices).
[platal.git] / htdocs / javascript / core.js
CommitLineData
819c6139
FB
1/***************************************************************************
2 * Copyright (C) 2003-2011 Polytechnique.org *
3 * http://opensource.polytechnique.org/ *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software *
17 * Foundation, Inc., *
18 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
19 ***************************************************************************/
20
ad884e35
FB
21// {{{ Assertion
22
23// }}}
819c6139
FB
24// {{{ jQuery object extension
25
26(function($) {
a2174267 27 var assert = function(condition, text) {
ad884e35
FB
28 if ($.isFunction(condition)) {
29 condition = condition();
30 }
31 if (condition) {
32 return this;
33 }
34 if (!text) {
35 throw "Assertion failed";
36 } else {
37 throw "Assertion failed: " + text;
38 }
a2174267 39 };
ad884e35
FB
40
41
819c6139
FB
42 /* Add new functions to jQuery namesapce */
43 $.extend({
c6e84b6d
FB
44 plURL: (function() {
45 var base;
46 return function(url) {
47 if (url.startsWith('http', true)) {
48 return url;
49 }
a2174267 50 if (typeof base === 'undefined') {
c6e84b6d
FB
51 base = $('head base');
52 if (base.length > 0) {
53 base = base.attr('href');
54 if (!base.endsWith('/')) {
55 base += '/';
56 }
57 } else {
58 base = '';
59 }
60 }
61 return base + url;
a2174267 62 };
c6e84b6d
FB
63 }()),
64
819c6139
FB
65 /* The goal of the following functions is to provide an AJAX API that
66 * take a different callback in case of HTTP success code (2XX) and in
67 * other cases.
68 */
69
70 xajax: function(source, method, data, onSuccess, onError, type) {
71 /* Shift argument */
72 if ($.isFunction(data)) {
73 type = type || onError;
74 onError = onSuccess;
75 onSuccess = data;
76 data = null;
77 }
a2174267 78 if (onError && !$.isFunction(onError)) {
819c6139
FB
79 type = type || onError;
80 onError = null;
81 }
82
83 function ajaxHandler(data, textStatus, xhr) {
a2174267 84 if (textStatus === 'success') {
819c6139
FB
85 if (onSuccess) {
86 onSuccess(data, textStatus, xhr);
87 }
a2174267 88 } else if (textStatus === 'error') {
819c6139
FB
89 if (onError) {
90 onError(data, textStatus, xhr);
91 } else {
92 alert("Une error s'est produite lors du traitement de la requête.\n"
93 + "Ta session a peut-être expiré");
94 }
95 }
96 }
97 return $.ajax({
c6e84b6d 98 url: $.plURL(source),
819c6139
FB
99 type: method,
100 success: ajaxHandler,
101 data : data,
102 dataType: type
103 });
104 },
105
106 xget: function(source, data, onSuccess, onError, type) {
107 return $.xajax(source, 'GET', data, onSuccess, onError, type);
108 },
109
110 xgetJSON: function(source, data, onSuccess, onError) {
111 return $.xget(source, data, onSuccess, onError, 'json');
112 },
113
114 xgetScript: function(source, onSuccess, onError) {
115 return $.xget(source, null, onSuccess, onError, 'script');
116 },
117
118 xgetText: function(source, data, onSuccess, onError) {
119 return $.xget(source, data, onSuccess, onError, 'text');
120 },
121
122 xpost: function(source, data, onSuccess, onError, type) {
123 return $.xajax(source, 'POST', data, onSuccess, onError, type);
124 },
125
126 closeOnEsc: function() {
127 return $(window).keydown(function (e) {
a2174267 128 if (e.keyCode === 27) {
819c6139
FB
129 window.close();
130 }
131 });
132 },
133
134 dynPost: function(action, key, value) {
135 var values;
a2174267
FB
136 var k;
137 var form;
138
819c6139
FB
139 if (!$.isArray(key)) {
140 values = { };
141 values[key] = value;
142 } else {
143 values = key;
144 }
a2174267 145 form = $('<form>', {
819c6139
FB
146 action: action,
147 method: 'post'
148 });
a2174267
FB
149 for (k in values) {
150 if (values.hasOwnProperty(k)) {
151 $('<input>', {
152 type: 'hidden',
153 name: k,
154 value: values[k]
155 }).appendTo(form);
156 }
819c6139
FB
157 }
158 $('body').appendTo(form);
159 form.submit();
ad884e35
FB
160 },
161
162 assert: assert
819c6139
FB
163 });
164
165 /* Add new functions to jQuery objects */
166 $.fn.extend({
167 tmpMessage: function(message, success) {
168 if (success) {
169 this.html("<img src='images/icons/wand.gif' alt='' /> " + message)
170 .css('color', 'green');
171 } else {
172 this.html("<img src='images/icons/error.gif' alt='' /> " + message)
173 .css('color', 'red');
174 }
175 return this.css('fontWeight', 'bold')
176 .show()
177 .delay(1000)
178 .fadeOut(500);
179 },
180
181 updateHtml: function(source, callback) {
182 var elements = this;
183 function handler(data) {
184 elements.html(data);
185 if (callback) {
186 callback(data);
187 }
188 }
189 $.xget(source, handler, 'text');
190 return this;
191 },
192
193 successMessage: function(source, message) {
194 var elements = this;
195 $.xget(source, function() {
196 elements.tmpMessage(message, true);
197 });
198 return this;
199 },
200
201 wiki: function(text, withTitle) {
a2174267 202 if (!text) {
819c6139
FB
203 return this.html('');
204 }
205 var url = 'wiki_preview';
206 if (!withTitle) {
207 url += '/notitile';
208 }
209 var $this = this;
210 $.post(url, { text: text },
211 function (data) {
212 $this.html(data);
213 }, 'text');
214 return this;
215 },
216
217 popWin: function(w, h) {
218 return this.click(function() {
219 window.open(this.href, '_blank',
220 'toolbar=0,location=0,directories=0,status=0,'
221 +'menubar=0,scrollbars=1,resizable=1,'
222 +'width='+w+',height='+h);
223 return false;
224 });
ad884e35
FB
225 },
226
227 assert: assert,
228
229 assertLength: function(len) {
230 return this.assert(function() {
a2174267 231 return $(this).length === len;
ad884e35
FB
232 });
233 },
234
235 assertId: function(id) {
236 return this.assert(function() {
a2174267 237 return $(this).attr('id') === id;
ad884e35
FB
238 });
239 },
240
241 assertClass: function(clazz) {
242 return this.assert(function() {
243 return $(this).hasClass(clazz);
244 });
819c6139
FB
245 }
246 });
a2174267 247}(jQuery));
819c6139
FB
248
249// }}}
250// {{{ function RegExp.escape()
251
252RegExp.escape = function(text) {
890974df
FB
253 if (!arguments.callee.sRE) {
254 var specials = [
255 '/', '.', '*', '+', '?', '|',
256 '(', ')', '[', ']', '{', '}',
257 '\\', '^' , '$'
258 ];
259 arguments.callee.sRE = new RegExp(
260 '(\\' + specials.join('|\\') + ')', 'g'
261 );
262 }
263 return text.replace(arguments.callee.sRE, '\\$1');
a2174267 264};
819c6139
FB
265
266// }}}
c6e84b6d
FB
267// {{{ String extension
268
269String.prototype.startsWith = function(str, caseInsensitive) {
270 var cmp = this;
271
272 if (str.length > this.length) {
273 return false;
274 }
275 if (caseInsensitive) {
276 str = str.toLowerCase();
277 cmp = cmp.toLowerCase();
278 }
a2174267
FB
279 return cmp.substr(0, str.length) === str;
280};
c6e84b6d
FB
281
282String.prototype.endsWith = function(str, caseInsensitive) {
283 var cmp = this;
284
285 if (str.length > this.length) {
286 return false;
287 }
288 if (caseInsensitive) {
289 str = str.toLowerCase();
290 cmp = cmp.toLowerCase();
291 }
a2174267
FB
292 return cmp.substr(cmp.length - str.length, str.length) === str;
293};
c6e84b6d
FB
294
295String.prototype.htmlEntities = function() {
296 return this.replace(/&/g,'&amp;')
297 .replace(new RegExp('<','g'),'&lt;')
298 .replace(/>/g,'&gt;');
a2174267 299};
c6e84b6d
FB
300
301String.prototype.contains = function(str, caseInsensitive) {
302 var cmp = this;
303 if (str.length > this.length) {
304 return false;
305 }
306 if (caseInsensitive) {
307 str = str.toLowerCase();
308 cmp = cmp.toLowerCase();
309 }
310 return cmp.indexOf(str) >= 0;
a2174267 311};
c6e84b6d
FB
312
313// }}}
819c6139
FB
314// {{{ PmWiki decoding
315
316Nix = {
890974df 317 map: null,
a2174267 318
890974df 319 convert: function(a) {
890974df 320 var s = '';
a2174267 321 Nix.init();
890974df
FB
322 for (i = 0; i < a.length ; i++) {
323 var b = a.charAt(i);
324 s += ((b >= 'A' && b <= 'Z') || (b >= 'a' && b <= 'z') ? Nix.map[b] : b);
325 }
326 return s;
327 },
a2174267 328
890974df 329 init: function() {
a2174267
FB
330 var map;
331 var s;
332
333 if (Nix.map !== null) {
890974df 334 return;
a2174267
FB
335 }
336 map = [ ];
337 s = 'abcdefghijklmnopqrstuvwxyz';
338 for (i = 0; i < s.length; i++) {
339 map[s.charAt(i)] = s.charAt((i+13) % 26);
340 }
341 for (i=0; i< s.length; i++) {
342 map[s.charAt(i).toUpperCase()] = s.charAt((i+13) % 26).toUpperCase();
343 }
344 Nix.map = map;
890974df 345 },
a2174267 346
890974df
FB
347 decode: function(a) {
348 document.write(Nix.convert(a));
349 }
a2174267 350};
819c6139
FB
351
352// }}}
353// {{{ preview wiki
354
355function previewWiki(idFrom, idTo, withTitle, idShow)
356{
357 $('#' + idTo).wiki($('#' + idFrom).val(), withTitle);
a2174267 358 if (idShow) {
819c6139
FB
359 $('#' + idShow).show();
360 }
361}
362
363// }}}
364
365// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: