]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/chrome/content/util/error.js
relative URL's can cause errors with window.open
[Evergreen.git] / Open-ILS / xul / staff_client / chrome / content / util / error.js
1 dump('entering util/error.js\n');
2
3 if (typeof util == 'undefined') util = {};
4 util.error = function () {
5
6         try {
7                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
8                 this.consoleService = Components.classes['@mozilla.org/consoleservice;1']
9                         .getService(Components.interfaces.nsIConsoleService);
10         } catch(E) {
11                 this.consoleDump = false;
12                 dump('util.error constructor: ' + E + '\n');
13         }
14
15         this.sdump_last_time = new Date();
16
17         this.OpenILS = {};
18
19         JSAN.use('util.sound'); this.sound = new util.sound();
20
21         return this;
22 };
23
24 util.error.prototype = {
25
26         'printDebug' : true,
27         'consoleDump' : false,
28         'debugDump' : true,
29         'fileDump' : false,
30         'alertDump' : false,
31         'arg_dump_full' : false,
32
33         'debug' : function(e){
34                 dump('-----------------------------------------\n' 
35                         + e + '\n-----------------------------------------\n' );
36         },
37
38         'sdump_levels' : {
39
40                 'D_NONE' : false, 
41                 'D_ALL' : false, 
42                 'D_ERROR' : { 'dump' : true, 'console' : true }, 
43                 'D_DEBUG' : { 'dump' : true, 'console' : true }, 
44                 'D_TRACE' :  { 'dump' : true }, 
45                 'D_ALERT' : { 'alert' : true, 'dump' : true },
46                 'D_WARN' : false, 
47                 'D_XULRUNNER' : false, 
48                 'D_DECK' : { 'dump' : true },
49                 'D_TRACE_ENTER' :  false, 
50                 'D_TRACE_EXIT' :  false, 
51                 'D_TIMEOUT' :  false, 
52                 'D_FILTER' : false,
53                 'D_CONSTRUCTOR' : false, 
54                 'D_FIREFOX' : false, 
55                 'D_LEGACY' : false, 
56                 'D_DATA_STASH' : { 'alert' : false }, 
57                 'D_DATA_RETRIEVE' : false,
58
59                 'D_CLAM' : false, 
60                 'D_PAGED_TREE' : false, 
61                 'D_GRID_LIST' : false, 
62                 'D_HTML_TABLE' : false,
63                 'D_TAB' : false, 
64                 'D_LIST' : false, 
65                 'D_LIST_DUMP_WITH_KEYS_ON_CLEAR' : false, 
66                 'D_LIST_DUMP_ON_CLEAR' : false,
67
68                 'D_AUTH' : { 'dump' : true }, 
69                 'D_OPAC' : { 'dump' : true }, 
70                 'D_CAT' : false, 
71                 'D_BROWSER' : { 'dump' : true },
72
73                 'D_PATRON_SEARCH' : false, 
74                 'D_PATRON_SEARCH_FORM' : false, 
75                 'D_PATRON_SEARCH_RESULTS' : false,
76
77                 'D_PATRON_DISPLAY' : false, 
78                 'D_PATRON_DISPLAY_STATUS' : false, 
79                 'D_PATRON_DISPLAY_CONTACT' : false,
80
81                 'D_PATRON_ITEMS' : false, 
82                 'D_PATRON_CHECKOUT_ITEMS' : false, 
83                 'D_PATRON_HOLDS' : false,
84                 'D_PATRON_BILLS' : false, 
85                 'D_PATRON_EDIT' : false,
86
87                 'D_CHECKIN' : false, 
88                 'D_CHECKIN_ITEMS' : false,
89
90                 'D_HOLD_CAPTURE' : false, 
91                 'D_HOLD_CAPTURE_ITEMS' : false,
92
93                 'D_PATRON_UTILS' : false, 
94                 'D_CIRC_UTILS' : false,
95
96                 'D_FILE' : false, 
97                 'D_EXPLODE' : false, 
98                 'D_FM_UTILS' : false, 
99                 'D_PRINT' : { 'dump' : true }, 
100                 'D_SES' : { 'dump' : true },
101                 'D_SES_FUNC' : false, 
102                 'D_SES_RESULT' : { 'dump' : true }, 
103                 'D_SES_ERROR' : { 'dump' : true, 'console' : true }, 
104                 'D_SPAWN' : false, 
105                 'D_STRING' : false,
106                 'D_UTIL' : false, 
107                 'D_WIN' : false, 
108                 'D_WIDGETS' : false
109         },
110
111         'filter_console_init' : function (p) {
112                 this.sdump('D_FILTER',this.arg_dump(arguments,{0:true}));
113
114                 var filterConsoleListener = {
115                         observe: function( msg ) {
116                                 try {
117                                         p.observe_msg( msg );
118                                 } catch(E) {
119                                         alert(E);
120                                 }
121                         },
122                         QueryInterface: function (iid) {
123                                 if (!iid.equals(Components.interfaces.nsIConsoleListener) &&
124                                         !iid.equals(Components.interfaces.nsISupports)) {
125                                                 throw Components.results.NS_ERROR_NO_INTERFACE;
126                                 }
127                                 return this;
128                         }
129                 };
130                 try {
131                         this.consoleService.registerListener(filterConsoleListener);    
132                 } catch(E) {
133                         alert(E);
134                 }
135
136                 this.sdump('D_TRACE_EXIT',this.arg_dump(arguments));
137         },
138
139         'sdump' : function (level,msg) {
140                 try {
141                         var now = new Date();
142                         var message = now.valueOf() + '\tdelta = ' + (now.valueOf() - this.sdump_last_time.valueOf()) + '\t' + level + '\n' + msg;
143                         if (this.sdump_levels['D_NONE']) return null;
144                         if (this.sdump_levels[level]||this.sdump_levels['D_ALL']) {
145                                 this.sdump_last_time = now;
146                                 if (this.debugDump || ( this.sdump_levels[level] && this.sdump_levels[level].debug ) ) this.debug(message);
147                                 if (this.alertDump || ( this.sdump_levels[level] && this.sdump_levels[level].alert ) ) alert(message);
148                                 if (this.consoleDump || ( this.sdump_levels[level] && this.sdump_levels[level].console ) ) {
149                                         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
150                                         this.consoleService.logStringMessage(message);
151                                 }
152                                 if (this.fileDump || ( this.sdump_levels[level] && this.sdump_levels[level].file ) ) {
153                                         if (level!='D_FILE') {
154                                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
155                                                 JSAN.use('util.file'); var master_log = new util.file('log');
156                                                 master_log.write_content('append',message); master_log.close();
157                                                 var specific_log = new util.file('log_'+level);
158                                                 specific_log.write_content('append',message); specific_log.close();
159                                         }
160                                 }
161                         }
162                 } catch(E) {
163                         dump('Calling sdump but ' + E + '\n');
164                 }
165         },
166
167         'arg_dump' : function (args,dump_these) {
168                 var s = '*>*>*> Called function ';
169                 try {
170                         if (!dump_these)
171                                 dump_these = {};
172                         s += args.callee.toString().match(/\w+/g)[1] + ' : ';
173                         for (var i = 0; i < args.length; i++)
174                                 s += typeof(args[i]) + ' ';
175                         s += '\n';
176                         for (var i = 0; i < args.length; i++)
177                                 if (dump_these[i]) {
178
179                                         var arg = args[i];
180                                         //dump('dump_these[i] = ' + dump_these[i] + '  arg = ' + arg + '\n');
181
182                                         if (typeof(dump_these[i])=='string') {
183
184                                                 if (dump_these[i].slice(0,1) == '.') {
185                                                         var cmd = 'arg' + dump_these[i];
186                                                         var result;
187                                                         try {
188                                                                 result = eval( cmd );
189                                                         } catch(E) {
190                                                                 result = cmd + ' ==> ' + E;
191                                                         }
192                                                         s += '\targ #' + i + ': ' + cmd + ' = ' + result;
193                                                 } else {
194                                                         var result;
195                                                         try {
196                                                                 result = eval( dump_these[i] );
197                                                         } catch(E) {
198                                                                 result = dump_these[i] + ' ==> ' + E;
199                                                         }
200                                                         s += '\targ #' + i + ': ' + result;
201                                                 }
202         
203                                         } else {
204                                                 s += '\targ #' + i + ' = ';
205                                                 try {
206                                                         //s += js2JSON( arg );
207                                                         s += arg;
208                                                 } catch(E) {
209                                                         s += arg;
210                                                 }
211                                         }
212         
213                                         s += '\n';
214                                         if (this.arg_dump_full)
215                                                 s += 'Definition: ' + args.callee.toString() + '\n';
216         
217                                 }
218                         return s;
219                 } catch(E) {
220                         return s + '\nDEBUG ME: ' + js2JSON(E) + '\n';
221                 }
222         },
223
224         'handle_error' : function (E,annoy) {
225                 var s = '';
226                 if (instanceOf(E,ex)) {
227                         s += E.err_msg();
228                         //s += '\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n';
229                         //s += 'This error was anticipated.\n\n';
230                         //s += js2JSON(E).substr(0,200) + '...\n\n';
231                         if (snd_bad) snd_bad();
232                 } else {
233                         s += '\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n';
234                         s += 'This is a bug that we will fix later.\n\n';
235                         try {
236                                 s += js2JSON(E).substr(0,1024) + '\n\n';
237                         } catch(E2) {
238                                 try {
239                                         s += E.substr(0,1024) + '\n\n';
240                                 } catch(E3) {
241                                         s += E + '\n\n';
242                                 }
243                         }
244                         if (snd_really_bad) snd_really_bad();
245                 }
246                 sdump('D_ERROR',s);
247                 if (annoy)
248                         this.s_alert(s);
249                 else
250                         alert(s);
251         },
252
253         's_alert' : function (s) { alert(s); },
254
255         'get_ilsevent' : function(status) {
256                 JSAN.use('OpenILS.data'); 
257                 this.OpenILS.data = new OpenILS.data(); this.OpenILS.data.init({'via':'stash'});
258                 return this.OpenILS.data.entities['ilsevent.'+status];
259         },
260
261         'standard_network_error_alert' : function(msg) {
262                 var obj = this;
263                 if (!msg) msg = '';
264                 var alert_msg = 'We experienced a network/server communication failure.  Please check your internet connection and try this action again.  Repeated failures may require attention from your local IT staff or your friendly Evergreen developers.\n\n' + msg.substr(0,100);
265                 obj.yns_alert(
266                         alert_msg,      
267                         'Communication Failure',
268                         'Ok', null, null, 'Check here to confirm this message'
269                 );
270         },
271
272         'standard_unexpected_error_alert' : function(msg,E) {
273                 var obj = this;
274                 if (typeof E.ilsevent != 'undefined') {
275                         if (E.ilsevent == 0 /* SUCCESS */ ) {
276                                 msg = "The action involved likely succeeded, however, this part of the software needs to be updated to better understand success messages from the server, so please let us know about it.";
277                         }
278                         if (E.ilsevent == -1 /* Network/Server Problem */ ) {
279                                 return obj.standard_network_error_alert(msg);
280                         }
281                         if (E.ilsevent == 5000 /* PERM_FAILURE */ ) {
282                                 msg = "The action involved likely failed due to insufficient permissions.  However, this part of the software needs to be updated to better understand permission messages from the server, so please let us know about it.";
283                         }
284                 }
285                 if (!msg) msg = '';
286                 var alert_msg = 'FIXME:  If you encounter this alert, please inform your IT/ILS helpdesk staff or your friendly Evergreen developers.\n\n' + (new Date()) + '\n\n' + msg + '\n\n' + (typeof E.ilsevent != 'undefined' ? E.textcode + '\n' + (E.desc ? E.desc + '\n' : '') : '') + ( typeof E.status != 'undefined' ? 'Status: ' + E.status + '\n': '' );
287                 obj.sdump('D_ERROR',msg + ' : ' + js2JSON(E));
288                 var r = obj.yns_alert(
289                         alert_msg,      
290                         'Unhandled Error',
291                         'Ok', 'Debug Output to send to Helpdesk', null, 'Check here to confirm this message',
292                         '/xul/server/skin/media/images/skull.png'
293                 );
294                 if (r == 1) {
295                         JSAN.use('util.window'); var win = new util.window();
296                         win.open(
297                                 'data:text/plain,' + window.escape( 'Please open a helpdesk ticket and include the following text: \n\n' + (new Date()) + '\n\n' + msg + '\n\n' + obj.pretty_print(js2JSON(E)) ),
298                                 'error_alert',
299                                 'chrome,resizable,width=700,height=500'
300                         );
301                 }
302                 if (r==2) {
303                         alert('Not Yet Implemented');
304                 }
305         },
306
307         'yns_alert' : function (s,title,b1,b2,b3,c,image) {
308
309                 try {
310
311                         if (location.href.match(/^chrome/)) return this.yns_alert_original(s,title,b1,b2,b3,c);
312
313                 /* The original purpose of yns_alert was to prevent errors from being scanned through accidentally with a barcode scanner.  
314                 However, this can be done in a less annoying manner by rolling our own dialog and not having any of the options in focus */
315
316                 /*
317                         s       = Message to display
318                         title   = Text in Title Bar
319                         b1      = Text for button 1
320                         b2      = Text for button 2
321                         b3      = Text for button 3
322                         c       = Text for confirmation checkbox.  null for no confirm
323                 */
324
325                 dump('yns_alert:\n\ts = ' + s + '\n\ttitle = ' + title + '\n\tb1 = ' + b1 + '\n\tb2 = ' + b2 + '\n\tb3 = ' + b3 + '\n\tc = ' + c + '\n');
326                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect UniversalBrowserWrite");
327
328                 this.sound.bad();
329
330
331                 //FIMXE - is that good enough of an escape job?
332                 s = s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
333
334                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml" flex="1">' 
335                         + '<groupbox flex="1" style="overflow: auto; border: solid thin red;"><caption label="' + (title) + '"/>';
336
337                 if (image) xml += '<hbox><image src="' + image + '"/><spacer flex="1"/></hbox>';
338                 xml += '<description style="font-size: large">' + (s)
339                         + '</description></groupbox><groupbox><caption label="Options"/><hbox>';
340                 var b1_key = b1 ? b1[0] : '';
341                 var b2_key = b2 ? b2[0] : '';
342                 var b3_key = b3 ? b3[0] : ''; /* FIXME - need to check for collisions */
343                 if (b1) xml += '<button id="b1" accesskey="' + b1_key + '" label="' + (b1) + '" name="fancy_submit" value="b1"/>'
344                 if (b2) xml += '<button id="b2" accesskey="' + b2_key + '" label="' + (b2) + '" name="fancy_submit" value="b2"/>'
345                 if (b3) xml += '<button id="b3" accesskey="' + b3_key + '" label="' + (b3) + '" name="fancy_submit" value="b3"/>'
346                 xml += '</hbox></groupbox></vbox>';
347                 JSAN.use('OpenILS.data');
348                 var data = new OpenILS.data(); data.init({'via':'stash'});
349                 data.temp_yns_xml = xml; data.stash('temp_yns_xml');
350                 var url = urls.XUL_FANCY_PROMPT + '?xml_in_stash=temp_yns_xml' + '&title=' + window.escape(title);
351                 if (xulG && xulG.url_prefix) url = xulG.url_prefix( url );
352                 window.open(
353                         url, 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500'
354                 );
355                 data.init({'via':'stash'});
356                 if (data.fancy_prompt_data != '') {
357                         switch(data.fancy_prompt_data.fancy_submit) {
358                                 case 'b1' : return 0; break;
359                                 case 'b2' : return 1; break;
360                                 case 'b3' : return 2; break;
361                         }
362                 } else {
363                         //return this.yns_alert(s,title,b1,b2,b3,c,image);
364                         return null;
365                 }
366
367                 } catch(E) {
368
369                         dump('yns_alert failed: ' + E + '\ns = ' + s + '\ntitle = ' + title + '\nb1 = ' + b1 + '\nb2 = ' + b2 + '\nb3 = ' + b3 + '\nc = ' + c + '\nimage = ' + image + '\n');
370
371                         this.yns_alert_original(s + '\n\nAlso, yns_alert failed: ' + E,title,b1,b2,b3,c);
372
373                 }
374         },
375
376         'yns_alert_formatted' : function (s,title,b1,b2,b3,c,image) {
377
378                 try {
379
380                         if (location.href.match(/^chrome/)) return this.yns_alert_original(s,title,b1,b2,b3,c);
381
382                 /* The original purpose of yns_alert was to prevent errors from being scanned through accidentally with a barcode scanner.  
383                 However, this can be done in a less annoying manner by rolling our own dialog and not having any of the options in focus */
384
385                 /*
386                         s       = Message to display
387                         title   = Text in Title Bar
388                         b1      = Text for button 1
389                         b2      = Text for button 2
390                         b3      = Text for button 3
391                         c       = Text for confirmation checkbox.  null for no confirm
392                 */
393
394                 dump('yns_alert:\n\ts = ' + s + '\n\ttitle = ' + title + '\n\tb1 = ' + b1 + '\n\tb2 = ' + b2 + '\n\tb3 = ' + b3 + '\n\tc = ' + c + '\n');
395                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect UniversalBrowserWrite");
396
397                 this.sound.bad();
398
399
400                 //FIMXE - is that good enough of an escape job?
401                 s = s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
402
403                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml" flex="1">' 
404                         + '<groupbox flex="1" style="overflow: auto; border: solid thin red;"><caption label="' + (title) + '"/>';
405
406                 if (image) xml += '<hbox><image src="' + image + '"/><spacer flex="1"/></hbox>';
407                 xml += '<description style="font-size: large"><html:pre style="font-size: large">' + (s)
408                         + '</html:pre></description></groupbox><groupbox><caption label="Options"/><hbox>';
409                 var b1_key = b1 ? b1[0] : '';
410                 var b2_key = b2 ? b2[0] : '';
411                 var b3_key = b3 ? b3[0] : ''; /* FIXME - need to check for collisions */
412                 if (b1) xml += '<button id="b1" accesskey="' + b1_key + '" label="' + (b1) + '" name="fancy_submit" value="b1"/>'
413                 if (b2) xml += '<button id="b2" accesskey="' + b2_key + '" label="' + (b2) + '" name="fancy_submit" value="b2"/>'
414                 if (b3) xml += '<button id="b3" accesskey="' + b3_key + '" label="' + (b3) + '" name="fancy_submit" value="b3"/>'
415                 xml += '</hbox></groupbox></vbox>';
416                 JSAN.use('OpenILS.data');
417                 var data = new OpenILS.data(); data.init({'via':'stash'});
418                 data.temp_yns_xml = xml; data.stash('temp_yns_xml');
419                 var url = urls.XUL_FANCY_PROMPT + '?xml_in_stash=temp_yns_xml' + '&title=' + window.escape(title);
420                 if (xulG && xulG.url_prefix) url = xulG.url_prefix( url );
421                 window.open(
422                         url, 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500'
423                 );
424                 data.init({'via':'stash'});
425                 if (data.fancy_prompt_data != '') {
426                         switch(data.fancy_prompt_data.fancy_submit) {
427                                 case 'b1' : return 0; break;
428                                 case 'b2' : return 1; break;
429                                 case 'b3' : return 2; break;
430                         }
431                 } else {
432                         //return this.yns_alert(s,title,b1,b2,b3,c,image);
433                         return null;
434                 }
435
436                 } catch(E) {
437
438                         alert('yns_alert_formatted failed: ' + E + '\ns = ' + s + '\ntitle = ' + title + '\nb1 = ' + b1 + '\nb2 = ' + b2 + '\nb3 = ' + b3 + '\nc = ' + c + '\nimage = ' + image + '\n');
439
440                 }
441
442         },
443
444         'yns_alert_original' : function (s,title,b1,b2,b3,c) {
445
446                 /*
447                         s       = Message to display
448                         title   = Text in Title Bar
449                         b1      = Text for button 1
450                         b2      = Text for button 2
451                         b3      = Text for button 3
452                         c       = Text for confirmation checkbox.  null for no confirm
453                 */
454
455                 dump('yns_alert:\n\ts = ' + s + '\n\ttitle = ' + title + '\n\tb1 = ' + b1 + '\n\tb2 = ' + b2 + '\n\tb3 = ' + b3 + '\n\tc = ' + c + '\n');
456                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
457
458                 this.sound.bad();
459
460                 // get a reference to the prompt service component.
461                 var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
462                         .getService(Components.interfaces.nsIPromptService);
463
464                 // set the buttons that will appear on the dialog. It should be
465                 // a set of constants multiplied by button position constants. In this case,
466                 // three buttons appear, Save, Cancel and a custom button.
467                 //var flags=promptService.BUTTON_TITLE_OK * promptService.BUTTON_POS_0 +
468                 //      promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1 +
469                 //      promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;
470                 var flags = promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
471                         promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1 +
472                         promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2; 
473
474                 // display the dialog box. The flags set above are passed
475                 // as the fourth argument. The next three arguments are custom labels used for
476                 // the buttons, which are used if BUTTON_TITLE_IS_STRING is assigned to a
477                 // particular button. The last two arguments are for an optional check box.
478                 var check = {};
479                 var rv = promptService.confirmEx(window,title, s, flags, b1, b2, b3, c, check);
480                 if (c && !check.value) {
481                         return this.yns_alert(s,title,b1,b2,b3,c);
482                 }
483                 return rv;
484         },
485
486         'print_tabs' : function(t) {
487                 var r = '';
488                 for (var j = 0; j < t; j++ ) { r = r + "\t"; }
489                 return r;
490         },
491
492         'pretty_print' : function(s) {
493                 var r = ''; var t = 0;
494                 for (var i in s) {
495                         if (s[i] == '{') {
496                                 r = r + "\n" + this.print_tabs(t) + s[i]; t++;
497                                 r = r + "\n" + this.print_tabs(t);
498                         } else if (s[i] == '[') {
499                                 r = r + "\n" + this.print_tabs(t) + s[i]; t++;
500                                 r = r + "\n" + this.print_tabs(t);
501                         } else if (s[i] == '}') {
502                                 t--; r = r + "\n" + this.print_tabs(t) + s[i];
503                                 r = r + "\n" + this.print_tabs(t);
504                         } else if (s[i] == ']') {
505                                 t--; r = r + "\n" + this.print_tabs(t) + s[i];
506                                 r = r + "\n" + this.print_tabs(t);
507                         } else if (s[i] == ',') {
508                                 r = r + s[i];
509                                 r = r + "\n" + this.print_tabs(t);
510                         } else {
511                                 r = r + s[i];
512                         }
513                 }
514                 return r;
515         },
516 }
517
518 dump('exiting util/error.js\n');