writing cookies as "" instead of calling .remove
[Evergreen.git] / Open-ILS / web / opac / common / js / opac_utils.js
1 /* - Request ------------------------------------------------------------- */
2
3 /* define it again here for pages that don't load RemoteRequest */
4 function isXUL() { try { if(IAMXUL) return true;}catch(e){return false;}; }
5
6
7 var cookieManager = new HTTP.Cookies();
8
9 var __ilsEvent; /* the last event the occurred */
10
11 function Request(type) {
12
13         var s = type.split(":");
14         if(s[2] == "1" && isXUL()) s[1] += ".staff";
15         this.request = new RemoteRequest(s[0], s[1]);
16         var p = [];
17
18         for( var x = 1; x!= arguments.length; x++ ) {
19                 p.push(arguments[x]);
20                 this.request.addParam(arguments[x]);
21         }
22
23         if( getDebug() ) {
24                 var str = "";
25                 for( var i = 0; i != p.length; i++ ) {
26                         if( i > 0 ) str += ", "
27                         str += js2JSON(p[i]);
28                 }
29                 _debug('request ' + s[0] + ' ' + s[1] + ' ' + str );
30         }
31 }
32
33 Request.prototype.callback = function(cal) {this.request.setCompleteCallback(cal);}
34 Request.prototype.send          = function(block){this.request.send(block);}
35 Request.prototype.result        = function(){return this.request.getResultObject();}
36
37 function showCanvas() {
38         for( var x in G.ui.altcanvas ) {
39                 hideMe(G.ui.altcanvas[x]);
40         }
41         hideMe(G.ui.common.loading);
42         unHideMe(G.ui.common.canvas_main);
43         try{G.ui.searchbar.text.focus();}catch(e){}
44 }
45
46 function swapCanvas(newNode) {
47         for( var x in G.ui.altcanvas ) 
48                 hideMe(G.ui.altcanvas[x]);
49
50         hideMe(G.ui.common.loading);
51         hideMe(G.ui.common.canvas_main);
52         unHideMe(newNode);
53 }
54
55 /* finds the name of the current page */
56 var currentPage = null;
57 function findCurrentPage() {
58         if(currentPage) return currentPage;
59
60         var pages = [];
61         for( var p in config.page ) pages.push(config.page[p]);
62         pages = pages.sort( function(a,b){ return - (a.length - b.length); } );
63
64         var path = location.pathname;
65         if(!path.match(/.*\.xml$/))
66                 path += "index.xml"; /* in case they go to  / */
67
68         var page = null;
69         for( var p in pages ) {
70                 if( path.indexOf(pages[p]) != -1)
71                         page = pages[p];
72         }
73
74         for( var p in config.page ) {
75                 if(config.page[p] == page) {
76                         currentPage = p;
77                         return p;
78                 }
79         }
80         return null;
81 }
82
83
84 /* sets all of the params values  ----------------------------- */
85 function initParams() {
86         var cgi = new CGI();    
87
88         TERM            = cgi.param(PARAM_TERM);
89         STYPE           = cgi.param(PARAM_STYPE);
90         FORM            = cgi.param(PARAM_FORM);
91         LOCATION        = parseInt(cgi.param(PARAM_LOCATION));
92         ORIGLOC = parseInt(cgi.param(PARAM_ORIGLOC));
93         DEPTH           = parseInt(cgi.param(PARAM_DEPTH));
94         OFFSET  = parseInt(cgi.param(PARAM_OFFSET));
95         COUNT           = parseInt(cgi.param(PARAM_COUNT));
96         HITCOUNT        = parseInt(cgi.param(PARAM_HITCOUNT));
97         MRID            = parseInt(cgi.param(PARAM_MRID));
98         RID             = parseInt(cgi.param(PARAM_RID));
99         AUTHTIME        = parseInt(cgi.param(PARAM_AUTHTIME));
100         ADVTERM = cgi.param(PARAM_ADVTERM);
101         ADVTYPE = cgi.param(PARAM_ADVTYPE);
102         RTYPE           = cgi.param(PARAM_RTYPE);
103         SORT            = cgi.param(PARAM_SORT);
104         SORT_DIR        = cgi.param(PARAM_SORT_DIR);
105         DEBUG           = cgi.param(PARAM_DEBUG);
106         CALLNUM = cgi.param(PARAM_CN);
107
108         /* set up some sane defaults */
109         if(isNaN(LOCATION))     LOCATION        = 1;
110         if(isNaN(DEPTH))                DEPTH           = 0;
111         if(isNaN(OFFSET))               OFFSET  = 0;
112         if(isNaN(COUNT))                COUNT           = 10;
113         if(isNaN(HITCOUNT))     HITCOUNT        = 0;
114         if(isNaN(MRID))         MRID            = 0;
115         if(isNaN(RID))                  RID             = 0;
116         if(isNaN(ORIGLOC))      ORIGLOC = 1;
117         if(isNaN(AUTHTIME))     AUTHTIME        = 0;
118         if(ADVTERM==null)               ADVTERM = "";
119 }
120
121 function initCookies() {
122         FONTSIZE = "regular";
123         var font = cookieManager.read(COOKIE_FONT);
124         scaleFonts(font);
125         if(font) FONTSIZE = font;
126         SKIN = cookieManager.read(COOKIE_SKIN);
127 }
128
129 /* URL param accessors */
130 function getTerm(){return TERM;}
131 function getStype(){return STYPE;}
132 function getLocation(){return LOCATION;}
133 function getDepth(){return DEPTH;}
134 function getForm(){return FORM;}
135 function getOffset(){return OFFSET;}
136 function getDisplayCount(){return COUNT;}
137 function getHitCount(){return HITCOUNT;}
138 function getMrid(){return MRID;};
139 function getRid(){return RID;};
140 function getOrigLocation(){return ORIGLOC;}
141 function getAuthtime() { return AUTHTIME; }
142 function getSearchBarExtras(){return SBEXTRAS;}
143 function getFontSize(){return FONTSIZE;};
144 function getSkin(){return SKIN;};
145 function getAdvTerm(){return ADVTERM;}
146 function getAdvType(){return ADVTYPE;}
147 function getRtype(){return RTYPE;}
148 function getSort(){return SORT;}
149 function getSortDir(){return SORT_DIR;}
150 function getDebug(){return DEBUG;}
151 function getCallnumber() { return CALLNUM; }
152
153
154 function findBasePath() {
155         var path = location.pathname;
156         if(!path.match(/.*\.xml$/)) path += "index.xml"; 
157         var idx = path.indexOf(config.page[findCurrentPage()]);
158         return path.substring(0, idx);
159 }
160
161 function findBaseURL(ssl) {
162         var path = findBasePath();
163         var proto = (ssl) ? "https:" : "http:";
164         return proto + "//" + location.host + path;
165         dump( 'ssl: ' + ssl + 'proto ' + proto );
166 }
167
168 /*
169 function buildISBNSrc(isbn) {
170         return "http://" + location.host + "/jackets/" + isbn;
171 }
172 */
173
174 function buildImageLink(name, ssl) {
175         return findBaseURL(ssl) + "../../../../images/" + name;
176 }
177
178 function buildExtrasLink(name, ssl) {
179         return findBaseURL(ssl) + "../../../../extras/" + name;
180 }
181
182 var consoleService;
183 function _debug(str) { 
184         try { dump(str + '\n'); } catch(e) {} 
185
186         if(!IE) {
187                 if(!consoleService) {
188                         try {
189                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
190                                 this.consoleService = Components.classes['@mozilla.org/consoleservice;1']
191                                         .getService(Components.interfaces.nsIConsoleService);
192                         } catch(e) {}
193                 }
194         
195                 try {
196                         if(consoleService) {
197                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
198                                 consoleService.logStringMessage(str + '\n');
199                         }
200                 } catch(e){}
201         }
202 }
203
204 function  buildOPACLink(args, slim, ssl) {
205
206         if(!args) args = {};
207         var string = "";
208
209         if(!slim) {
210                 string = findBaseURL(ssl);
211                 if(args.page) string += config.page[args.page];
212                 else string += config.page[findCurrentPage()];
213         }
214
215         string += "?";
216
217         for( var x in args ) {
218                 var v = args[x];
219                 if(x == "page" || v == null || v == undefined || v+'' == 'NaN' ) continue;
220                 if(x == PARAM_OFFSET && v == 0) continue;
221                 if(x == PARAM_LOCATION && v == 1) continue;
222                 if(x == PARAM_DEPTH && v == 0) continue;
223                 if(x == PARAM_COUNT && v == 10) continue;
224                 if(x == PARAM_FORM && v == 'all' ) continue;
225                 if( instanceOf(v, Array) && v.length ) {
226                         for( var i = 0; i < v.length; i++ ) {
227                                 string += "&" + x + "=" + encodeURIComponent(v[i]);
228                         }
229                 } else {
230                         string += "&" + x + "=" + encodeURIComponent(v);
231                 }
232         }
233
234         if(getDebug())
235                 string += _appendParam(DEBUG,   PARAM_DEBUG, args, getDebug, string);
236         if(getOrigLocation() != 1) 
237                 string += _appendParam(ORIGLOC, PARAM_ORIGLOC, args, getOrigLocation, string);
238         if(getTerm()) 
239                 string += _appendParam(TERM,            PARAM_TERM, args, getTerm, string);
240         if(getStype()) 
241                 string += _appendParam(STYPE,           PARAM_STYPE, args, getStype, string);
242         if(getLocation() != 1) 
243                 string += _appendParam(LOCATION, PARAM_LOCATION, args, getLocation, string);
244         if(getDepth() != 0) 
245                 string += _appendParam(DEPTH,           PARAM_DEPTH, args, getDepth, string);
246         if(getForm() && (getForm() != 'all') ) 
247                 string += _appendParam(FORM,            PARAM_FORM, args, getForm, string);
248         if(getOffset() != 0) 
249                 string += _appendParam(OFFSET,  PARAM_OFFSET, args, getOffset, string);
250         if(getDisplayCount() != 10) 
251                 string += _appendParam(COUNT,           PARAM_COUNT, args, getDisplayCount, string);
252         if(getHitCount()) 
253                 string += _appendParam(HITCOUNT, PARAM_HITCOUNT, args, getHitCount, string);
254         if(getMrid())
255                 string += _appendParam(MRID,            PARAM_MRID, args, getMrid, string);
256         if(getRid())
257                 string += _appendParam(RID,             PARAM_RID, args, getRid, string);
258         if(getAuthtime())
259                 string += _appendParam(AUTHTIME,        PARAM_AUTHTIME, args, getAuthtime, string);
260         if(getAdvTerm())
261                 string += _appendParam(ADVTERM, PARAM_ADVTERM, args, getAdvTerm, string);
262         if(getAdvType())
263                 string += _appendParam(ADVTYPE, PARAM_ADVTYPE, args, getAdvType, string);
264         if(getRtype())
265                 string += _appendParam(RTYPE,           PARAM_RTYPE, args, getRtype, string);
266
267         return string.replace(/\&$/,'').replace(/\?\&/,"?");    
268 }
269
270 function _appendParam( fieldVar, fieldName, overrideArgs, getFunc, string ) {
271         var ret = "";
272         if( fieldVar != null && (fieldVar +'' != 'NaN') && overrideArgs[fieldName] == null ) 
273                 ret = "&" + fieldName + "=" + encodeURIComponent(getFunc());
274         return ret;
275 }
276
277 /* ----------------------------------------------------------------------- */
278 function cleanISBN(isbn) {
279    if(isbn) {
280       isbn = isbn.toString().replace(/^\s+/,"");
281       var idx = isbn.indexOf(" ");
282       if(idx > -1) { isbn = isbn.substring(0, idx); }
283    } else isbn = "";
284    return isbn;
285 }       
286
287
288 /* builds a link that goes to the title listings for a metarecord */
289 function buildTitleLink(rec, link) {
290         if(!rec) return;
291         link.appendChild(text(normalize(truncate(rec.title(), 65))));
292         var args = {};
293         args.page = RRESULT;
294         args[PARAM_OFFSET] = 0;
295         args[PARAM_MRID] = rec.doc_id();
296         args[PARAM_RTYPE] = RTYPE_MRID;
297         link.setAttribute("href", buildOPACLink(args));
298 }
299
300 function buildTitleDetailLink(rec, link) {
301         if(!rec) return;
302         link.appendChild(text(normalize(truncate(rec.title(), 65))));
303         var args = {};
304         args.page = RDETAIL;
305         args[PARAM_OFFSET] = 0;
306         args[PARAM_RID] = rec.doc_id();
307         link.setAttribute("href", buildOPACLink(args));
308 }
309
310 /* 'type' is one of STYPE_AUTHOR, STYPE_SUBJECT, ... found in config.js 
311         'trunc' is the number of characters to show in the string, defaults to 65 */
312 function buildSearchLink(type, string, linknode, trunc) {
313         if(!trunc) trunc = 65;
314         var args = {};
315         args.page = MRESULT;
316         args[PARAM_OFFSET] = 0;
317         args[PARAM_TERM] = string;
318         args[PARAM_STYPE] = type;
319         linknode.appendChild(text(normalize(truncate(string, trunc))));
320         linknode.setAttribute("href", buildOPACLink(args));
321 }
322
323
324 /* ----------------------------------------------------------------------- */
325 /* user session handling */
326 /* ----------------------------------------------------------------------- */
327 /* session is the login session.  If no session is provided, we attempt
328         to find one in the cookies.  If 'force' is true we retrieve the 
329         user from the server even if there is already a global user present.
330         if ses != G.user.session, we also force a grab */
331 function grabUser(ses, force) {
332
333         if(!ses && isXUL()) ses = xulG['authtoken'];
334
335         if(!ses) {
336                 ses = cookieManager.read(COOKIE_SES);
337                 /* https cookies don't show up in http servers.. */
338         }
339
340         if(!ses) return false;
341
342         if(!force) 
343                 if(G.user && G.user.session == ses)
344                         return G.user;
345
346         /* first make sure the session is valid */
347         var request = new Request(FETCH_SESSION, ses, 1 );
348         request.send(true);
349         var user = request.result();
350
351         if(checkILSEvent(user)) {
352                 __ilsEvent = user;
353                 doLogout();
354                 return false; /* unable to grab the session */
355         }
356
357         if( !(typeof user == 'object' && user._isfieldmapper) ) {
358                 doLogout();
359                 return false;
360         }
361
362         G.user = user;
363         G.user.fleshed = false;
364         G.user.session = ses;
365         cookieManager.write(COOKIE_SES, ses, '+1d');
366
367         grabUserPrefs();
368         if(G.user.prefs['opac.hits_per_page'])
369                 COUNT = parseInt(G.user.prefs['opac.hits_per_page']);
370
371         if(G.user.prefs[PREF_DEF_FONT]) 
372                 setFontSize(G.user.prefs[PREF_DEF_FONT]);
373
374         var at = getAuthtime();
375         //if(isXUL()) at = xulG['authtime'];
376
377         if(at && !isXUL()) new AuthTimer(at).run(); 
378         return G.user;
379 }
380
381
382 /* sets the 'prefs' field of the user object to their preferences 
383         and returns the preferences */
384 function grabUserPrefs(user, force) {
385         if(user == null) user = G.user;
386         if(!force && user.prefs) return user.prefs;     
387         var req = new Request(FETCH_USER_PREFS, user.session, user.id());
388         req.send(true);
389         user.prefs = req.result();
390         return user.prefs;
391 }
392
393 function grabFleshedUser() {
394
395         if(!G.user || !G.user.session) {
396                 grabUser();     
397                 if(!G.user || !G.user.session) return null;
398         }
399
400         if(G.user.fleshed) return G.user;
401
402    var req = new Request(FETCH_FLESHED_USER, G.user.session);
403         req.send(true);
404
405         G.user = req.result();
406
407         if(!G.user || G.user.length == 0) { 
408                 G.user = null; return false; 
409                 cookieManager.write(COOKIE_SES,"");
410         }
411
412         G.user.session = ses;
413         G.user.fleshed = true;
414
415         cookieManager.write(COOKIE_SES, ses, '+1y'); /*  update the cookie */
416         return G.user;
417 }
418
419 function checkUserSkin(new_skin) {
420
421         return; /* XXX do some debugging with this... */
422
423         var user_skin = getSkin();
424         var cur_skin = grabSkinFromURL();
425
426         if(new_skin) user_skin = new_skin;
427
428         if(!user_skin) {
429
430                 if(grabUser()) {
431                         if(grabUserPrefs()) {
432                                 user_skin = G.user.prefs["opac.skin"];
433                                 cookieManager.write( COOKIE_SKIN, user_skin, '+1y' );
434                         }
435                 }
436         }
437
438         if(!user_skin) return;
439
440         if( cur_skin != user_skin ) {
441                 var url = buildOPACLink();
442                 goTo(url.replace(cur_skin, user_skin));
443         }
444 }
445
446 function updateUserSetting(setting, value, user) {
447         if(user == null) user = G.user;
448         var a = {};
449         a[setting] = value;
450         var req = new Request( UPDATE_USER_PREFS, user.session, a );
451         req.send(true);
452         return req.result();
453 }
454
455 function commitUserPrefs() {
456         var req = new Request( 
457                 UPDATE_USER_PREFS, G.user.session, null, G.user.prefs );
458         req.send(true);
459         return req.result();
460 }
461
462 function grabSkinFromURL() {
463         var path = findBasePath();
464         path = path.replace("/xml/", "");
465         var skin = "";
466         for( var i = path.length - 1; i >= 0; i-- ) {
467                 var ch = path.charAt(i);
468                 if(ch == "/") break;
469                 skin += ch;
470         }
471
472         var skin2 = "";
473         for( i = skin.length - 1; i >= 0; i--)
474                 skin2 += skin.charAt(i);
475
476         return skin2;
477 }
478
479
480 /* returns a fleshed G.user on success, false on failure */
481 function doLogin() {
482
483         abortAllRequests();
484
485         var uname = G.ui.login.username.value;
486         var passwd = G.ui.login.password.value; 
487
488         var init_request = new Request( LOGIN_INIT, uname );
489    init_request.send(true);
490    var seed = init_request.result();
491
492    if( ! seed || seed == '0') {
493       alert( "Error Communicating with Authentication Server" );
494       return null;
495    }
496
497         var args = {
498                 password : hex_md5(seed + hex_md5(passwd)), 
499                 type            : "opac", 
500                 org             : getOrigLocation()
501         };
502
503         if( uname.match(REGEX_BARCODE) ) args.barcode = uname; /* make this better */
504         else args.username = uname;
505
506    var auth_request = new Request( LOGIN_COMPLETE, args );
507
508    auth_request.send(true);
509    var auth_result = auth_request.result();
510
511         var code = checkILSEvent(auth_result);
512         if(code) { alertILSEvent(code); return null; }
513
514         AUTHTIME = parseInt(auth_result.payload.authtime);
515         var u = grabUser(auth_result.payload.authtoken, true);
516         if(u) runEvt( "common", "locationChanged", u.home_ou(), findOrgDepth(u.home_ou()) );
517
518         checkUserSkin();
519
520         return u;
521 }
522
523 function doLogout(noredirect) {
524
525         /* cancel everything else */
526         abortAllRequests();
527
528         /* be nice and delete the session from the server */
529         if(G.user && G.user.session) { 
530                 var req = new Request(LOGIN_DELETE, G.user.session);
531       req.send(true);
532                 try { req.result(); } catch(E){}
533     }
534
535         G.user = null;
536         cookieManager.write(COOKIE_SES, "");
537         cookieManager.write(COOKIE_SKIN, "");
538         checkUserSkin("default");
539         COUNT = 10;
540
541         var args = {};
542         args[PARAM_TERM] = "";
543         args[PARAM_LOCATION] = globalOrgTree.id();
544         args[PARAM_DEPTH] = findOrgDepth(globalOrgTree);
545         args.page = "home";
546
547         var nored = false;
548         try{ if(isFrontPage) nored = true; } catch(e){nored = false;}
549         if(!nored) goTo(buildOPACLink(args));
550 }
551
552
553 function hideMe(obj) { addCSSClass(obj, config.css.hide_me); } 
554 function unHideMe(obj) { removeCSSClass(obj, config.css.hide_me); }
555
556
557 /* ----------------------------------------------------------------------- */
558 /* build the org tree */
559 /* ----------------------------------------------------------------------- */
560 function drawOrgTree() {
561         //setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 10 );
562         setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 1 );
563 }
564         
565 var orgTreeSelector;
566 function buildOrgSelector(node) {
567         var tree = new SlimTree(node,'orgTreeSelector');
568         orgTreeSelector = tree;
569         for( var i in orgArraySearcher ) { 
570                 var node = orgArraySearcher[i];
571                 if( node == null ) continue;
572                 if(node.parent_ou() == null)
573                         tree.addNode(node.id(), -1, node.name(), 
574                                 "javascript:orgSelect(" + node.id() + ");", node.name());
575                 else {
576                         tree.addNode(node.id(), findOrgUnit(node.parent_ou()).id(), node.name(), 
577                                 "javascript:orgSelect(" + node.id() + ");", node.name());
578                 }
579         }
580         hideMe($('org_loading_div'));
581         unHideMe($('org_selector_tip'));
582         return tree;
583 }
584
585 function orgSelect(id) {
586         showCanvas();
587         runEvt("common", "locationChanged", id, findOrgDepth(id) );
588
589         removeChildren(G.ui.common.now_searching);
590         G.ui.common.now_searching.appendChild(text(findOrgUnit(id).name()));
591 }
592
593 //var fontCookie = new HTTP.Cookies();
594
595 function setFontSize(size) {
596         scaleFonts(size);
597         cookieManager.write(COOKIE_FONT, size, '+1y');
598 }
599
600
601 var resourceFormats = [
602    "text",
603    "moving image",
604    "sound recording", "software, multimedia",
605    "still images",
606    "cartographic",
607    "mixed material",
608    "notated music",
609    "three dimensional object" ];
610
611
612 function modsFormatToMARC(format) {
613    switch(format) {
614       case "text":
615          return "at";
616       case "moving image":
617          return "g";
618       case "sound recording":
619          return "ij";
620       case "sound recording-nonmusical":
621          return "i";
622       case "sound recording-musical":
623          return "j";
624       case "software, multimedia":
625          return "m";
626       case "still images":
627          return "k";
628       case "cartographic":
629          return "ef";
630       case "mixed material":
631          return "op";
632       case "notated music":
633          return "cd";
634       case "three dimensional object":
635          return "r";
636    }
637    return "at";
638 }
639
640
641 function MARCFormatToMods(format) {
642    switch(format) {
643       case "a":
644       case "t":
645          return "text";
646       case "g":
647          return "moving image";
648       case "i":
649          return "sound recording-nonmusical";
650       case "j":
651          return "sound recording-musical";
652       case "m":
653          return "software, multimedia";
654       case "k":
655          return "still images";
656       case "e":
657       case "f":
658          return "cartographic";
659       case "o":
660       case "p":
661          return "mixed material";
662       case "c":
663       case "d":
664          return "notated music";
665       case "r":
666          return "three dimensional object";
667    }
668    return "text";
669 }
670
671 function setResourcePic( img, resource ) {
672         img.setAttribute( "src", "../../../../images/tor/" + resource + ".jpg");
673         img.title = resource;
674 }
675
676
677
678 function msg( text ) {
679         try { alert( text ); } catch(e) {}
680 }
681
682 function findRecord(id,type) {
683         try {
684                 for( var i = 0; i != recordsCache.length; i++ ) {
685                         var rec = recordsCache[i];
686                         if( rec && rec.doc_id() == id ) return rec;
687                 }
688         } catch(E){}
689         var meth = FETCH_RMODS
690         if(type == 'M') meth = FETCH_MRMODS;
691         var req = new Request(meth, id);
692         req.send(true);
693         return req.result();
694 }
695
696 function Timer(name, node){
697         this.name = name;
698         this.count = 1;
699         this.node = node;
700 }
701 Timer.prototype.start = 
702         function(){_timerRun(this.name);}
703 Timer.prototype.stop = 
704         function(){this.done = true;}
705 function _timerRun(tname) {
706         var _t;
707         eval('_t='+tname);
708         if(_t.done) return;
709         if(_t.count > 100) return;
710         var str = ' . ';
711         if( (_t.count % 5) == 0 ) 
712                 str = _t.count / 5;
713         _t.node.appendChild(text(str));
714         setTimeout("_timerRun('"+tname+"');", 200);
715         _t.count++;
716 }
717
718 function checkILSEvent(obj) {
719         if( obj.ilsevent != null && obj.ilsevent != 0 )
720                 return parseInt(obj.ilsevent);
721         return null;
722 }
723 function alertILSEvent(code, msg) {
724    if(!msg) msg = "";
725         alert( msg + '\n' + $('ilsevent.' + code).innerHTML );
726 }
727
728
729 var __authTimer;
730 function AuthTimer(time) { 
731         this.time = (time - LOGOUT_WARNING_TIME) * 1000; 
732         __authTimer = this;
733 }
734
735 AuthTimer.prototype.run = function() {
736         setTimeout('_authTimerAlert()', this.time);
737 }
738
739 function _authTimerAlert() {
740         alert( $('auth_session_expiring').innerHTML );
741         if(!grabUser(null, true)) doLogout();
742 }
743
744
745 function grabUserByBarcode( authtoken, barcode ) {
746         var req = new Request( FETCH_USER_BYBARCODE, authtoken, barcode );
747         req.send(true);
748         return req.result();
749 }
750
751
752 function goHome() {
753         goTo(buildOPACLink({page:HOME}));
754 }
755
756
757 function buildOrgSel(selector, org, offset) {
758         insertSelectorVal( selector, -1, 
759                 org.name(), org.id(), null, findOrgDepth(org) - offset );
760         for( var c in org.children() )
761                 buildOrgSel( selector, org.children()[c], offset);
762 }
763
764