Properly plug the error callback.
[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 40
b291bc17 41 var ajaxParams = function(onSuccess, onError, extraParameters) {
aa2ac758
FB
42 function errorHandler()
43 {
44 if (onError) {
45 return onError.apply(this, arguments);
46 } else {
47 alert("Une error s'est produite lors du traitement de la requête.\n"
48 + "Ta session a peut-être expiré");
b291bc17 49 }
aa2ac758
FB
50 }
51
52 return $.extend({
53 success: onSuccess,
54 error: errorHandler
b291bc17
FB
55 }, extraParameters);
56 };
ad884e35 57
819c6139
FB
58 /* Add new functions to jQuery namesapce */
59 $.extend({
b291bc17
FB
60 xapiVersion: '1',
61
c6e84b6d
FB
62 plURL: (function() {
63 var base;
64 return function(url) {
65 if (url.startsWith('http', true)) {
66 return url;
67 }
a2174267 68 if (typeof base === 'undefined') {
c6e84b6d
FB
69 base = $('head base');
70 if (base.length > 0) {
71 base = base.attr('href');
72 if (!base.endsWith('/')) {
73 base += '/';
74 }
75 } else {
76 base = '';
77 }
78 }
79 return base + url;
a2174267 80 };
c6e84b6d
FB
81 }()),
82
819c6139
FB
83 /* The goal of the following functions is to provide an AJAX API that
84 * take a different callback in case of HTTP success code (2XX) and in
85 * other cases.
86 */
87
88 xajax: function(source, method, data, onSuccess, onError, type) {
89 /* Shift argument */
90 if ($.isFunction(data)) {
91 type = type || onError;
92 onError = onSuccess;
93 onSuccess = data;
94 data = null;
95 }
a2174267 96 if (onError && !$.isFunction(onError)) {
819c6139
FB
97 type = type || onError;
98 onError = null;
99 }
100
b291bc17 101 return $.ajax(ajaxParams(onSuccess, onError, {
c6e84b6d 102 url: $.plURL(source),
819c6139 103 type: method,
819c6139
FB
104 data : data,
105 dataType: type
b291bc17
FB
106 }));
107 },
108
109 xapi: function(apicall, payload, onSuccess, onError) {
110 if ($.isFunction(payload)) {
111 onError = onSuccess;
112 onSuccess = payload;
113 }
114
115 return $.ajax(ajaxParams(onSuccess, onError, {
116 url: $.plURL('api/' + $.xapiVersion + '/' + apicall),
117 type: 'POST',
118 data: JSON.stringify(payload),
119 dataType: 'json',
120 contentType: 'text/javascript'
121 }));
819c6139
FB
122 },
123
124 xget: function(source, data, onSuccess, onError, type) {
125 return $.xajax(source, 'GET', data, onSuccess, onError, type);
126 },
127
128 xgetJSON: function(source, data, onSuccess, onError) {
129 return $.xget(source, data, onSuccess, onError, 'json');
130 },
131
132 xgetScript: function(source, onSuccess, onError) {
133 return $.xget(source, null, onSuccess, onError, 'script');
134 },
135
136 xgetText: function(source, data, onSuccess, onError) {
137 return $.xget(source, data, onSuccess, onError, 'text');
138 },
139
140 xpost: function(source, data, onSuccess, onError, type) {
141 return $.xajax(source, 'POST', data, onSuccess, onError, type);
142 },
143
144 closeOnEsc: function() {
145 return $(window).keydown(function (e) {
a2174267 146 if (e.keyCode === 27) {
819c6139
FB
147 window.close();
148 }
149 });
150 },
151
152 dynPost: function(action, key, value) {
153 var values;
a2174267
FB
154 var k;
155 var form;
156
819c6139
FB
157 if (!$.isArray(key)) {
158 values = { };
159 values[key] = value;
160 } else {
161 values = key;
162 }
a2174267 163 form = $('<form>', {
819c6139
FB
164 action: action,
165 method: 'post'
166 });
a2174267
FB
167 for (k in values) {
168 if (values.hasOwnProperty(k)) {
169 $('<input>', {
170 type: 'hidden',
171 name: k,
172 value: values[k]
173 }).appendTo(form);
174 }
819c6139
FB
175 }
176 $('body').appendTo(form);
177 form.submit();
ad884e35
FB
178 },
179
180 assert: assert
819c6139
FB
181 });
182
183 /* Add new functions to jQuery objects */
184 $.fn.extend({
185 tmpMessage: function(message, success) {
186 if (success) {
187 this.html("<img src='images/icons/wand.gif' alt='' /> " + message)
188 .css('color', 'green');
189 } else {
190 this.html("<img src='images/icons/error.gif' alt='' /> " + message)
191 .css('color', 'red');
192 }
193 return this.css('fontWeight', 'bold')
194 .show()
195 .delay(1000)
196 .fadeOut(500);
197 },
198
199 updateHtml: function(source, callback) {
200 var elements = this;
201 function handler(data) {
202 elements.html(data);
203 if (callback) {
204 callback(data);
205 }
206 }
207 $.xget(source, handler, 'text');
208 return this;
209 },
210
211 successMessage: function(source, message) {
212 var elements = this;
213 $.xget(source, function() {
214 elements.tmpMessage(message, true);
215 });
216 return this;
217 },
218
219 wiki: function(text, withTitle) {
a2174267 220 if (!text) {
819c6139
FB
221 return this.html('');
222 }
223 var url = 'wiki_preview';
224 if (!withTitle) {
225 url += '/notitile';
226 }
227 var $this = this;
228 $.post(url, { text: text },
229 function (data) {
230 $this.html(data);
231 }, 'text');
232 return this;
233 },
234
235 popWin: function(w, h) {
236 return this.click(function() {
237 window.open(this.href, '_blank',
238 'toolbar=0,location=0,directories=0,status=0,'
239 +'menubar=0,scrollbars=1,resizable=1,'
240 +'width='+w+',height='+h);
241 return false;
242 });
ad884e35
FB
243 },
244
245 assert: assert,
246
247 assertLength: function(len) {
248 return this.assert(function() {
a2174267 249 return $(this).length === len;
ad884e35
FB
250 });
251 },
252
253 assertId: function(id) {
254 return this.assert(function() {
a2174267 255 return $(this).attr('id') === id;
ad884e35
FB
256 });
257 },
258
259 assertClass: function(clazz) {
260 return this.assert(function() {
261 return $(this).hasClass(clazz);
262 });
819c6139
FB
263 }
264 });
a2174267 265}(jQuery));
819c6139
FB
266
267// }}}
268// {{{ function RegExp.escape()
269
270RegExp.escape = function(text) {
890974df
FB
271 if (!arguments.callee.sRE) {
272 var specials = [
273 '/', '.', '*', '+', '?', '|',
274 '(', ')', '[', ']', '{', '}',
275 '\\', '^' , '$'
276 ];
277 arguments.callee.sRE = new RegExp(
278 '(\\' + specials.join('|\\') + ')', 'g'
279 );
280 }
281 return text.replace(arguments.callee.sRE, '\\$1');
a2174267 282};
819c6139
FB
283
284// }}}
c6e84b6d
FB
285// {{{ String extension
286
287String.prototype.startsWith = function(str, caseInsensitive) {
288 var cmp = this;
289
290 if (str.length > this.length) {
291 return false;
292 }
293 if (caseInsensitive) {
294 str = str.toLowerCase();
295 cmp = cmp.toLowerCase();
296 }
a2174267
FB
297 return cmp.substr(0, str.length) === str;
298};
c6e84b6d
FB
299
300String.prototype.endsWith = function(str, caseInsensitive) {
301 var cmp = this;
302
303 if (str.length > this.length) {
304 return false;
305 }
306 if (caseInsensitive) {
307 str = str.toLowerCase();
308 cmp = cmp.toLowerCase();
309 }
a2174267
FB
310 return cmp.substr(cmp.length - str.length, str.length) === str;
311};
c6e84b6d
FB
312
313String.prototype.htmlEntities = function() {
314 return this.replace(/&/g,'&amp;')
315 .replace(new RegExp('<','g'),'&lt;')
316 .replace(/>/g,'&gt;');
a2174267 317};
c6e84b6d
FB
318
319String.prototype.contains = function(str, caseInsensitive) {
320 var cmp = this;
321 if (str.length > this.length) {
322 return false;
323 }
324 if (caseInsensitive) {
325 str = str.toLowerCase();
326 cmp = cmp.toLowerCase();
327 }
328 return cmp.indexOf(str) >= 0;
a2174267 329};
c6e84b6d
FB
330
331// }}}
819c6139
FB
332// {{{ PmWiki decoding
333
334Nix = {
890974df 335 map: null,
a2174267 336
890974df 337 convert: function(a) {
890974df 338 var s = '';
a2174267 339 Nix.init();
890974df
FB
340 for (i = 0; i < a.length ; i++) {
341 var b = a.charAt(i);
342 s += ((b >= 'A' && b <= 'Z') || (b >= 'a' && b <= 'z') ? Nix.map[b] : b);
343 }
344 return s;
345 },
a2174267 346
890974df 347 init: function() {
a2174267
FB
348 var map;
349 var s;
350
351 if (Nix.map !== null) {
890974df 352 return;
a2174267
FB
353 }
354 map = [ ];
355 s = 'abcdefghijklmnopqrstuvwxyz';
356 for (i = 0; i < s.length; i++) {
357 map[s.charAt(i)] = s.charAt((i+13) % 26);
358 }
359 for (i=0; i< s.length; i++) {
360 map[s.charAt(i).toUpperCase()] = s.charAt((i+13) % 26).toUpperCase();
361 }
362 Nix.map = map;
890974df 363 },
a2174267 364
890974df
FB
365 decode: function(a) {
366 document.write(Nix.convert(a));
367 }
a2174267 368};
819c6139
FB
369
370// }}}
371// {{{ preview wiki
372
373function previewWiki(idFrom, idTo, withTitle, idShow)
374{
375 $('#' + idTo).wiki($('#' + idFrom).val(), withTitle);
a2174267 376 if (idShow) {
819c6139
FB
377 $('#' + idShow).show();
378 }
379}
380
381// }}}
382
383// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: