]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/opac_utils.js
Committing initial limit-to-available and sort options on record result page
[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 var DEBUGSLIM;
12 function Request(type) {
13
14         var s = type.split(":");
15         if(s[2] == "1" && isXUL()) s[1] += ".staff";
16         this.request = new RemoteRequest(s[0], s[1]);
17         var p = [];
18
19         if(isXUL()) {
20                 if(!location.href.match(/^https:/))
21                         this.request.setSecure(false);
22
23         } else {
24
25                 if( G.user && G.user.session ) {
26                         /* if the user is logged in, all activity resets the timeout 
27                                 This is not entirely accurate in the sense that not all 
28                                 requests will reset the server timeout - this should
29                                 get close enough, however.
30                         */
31                         var at = getAuthtime();
32                         if(at) new AuthTimer(at).run(); 
33                 }
34         }
35
36         for( var x = 1; x!= arguments.length; x++ ) {
37                 p.push(arguments[x]);
38                 this.request.addParam(arguments[x]);
39         }
40
41         if( getDebug() ) {
42                 var str = "";
43                 for( var i = 0; i != p.length; i++ ) {
44                         if( i > 0 ) str += ", "
45                         str += js2JSON(p[i]);
46                 }
47                 _debug('request ' + s[0] + ' ' + s[1] + ' ' + str );
48
49         } else if( DEBUGSLIM ) {
50                 _debug('request ' + s[1]);
51         }
52 }
53
54 Request.prototype.callback = function(cal) {this.request.setCompleteCallback(cal);}
55 Request.prototype.send          = function(block){this.request.send(block);}
56 Request.prototype.result        = function(){return this.request.getResultObject();}
57
58 function showCanvas() {
59         for( var x in G.ui.altcanvas ) {
60                 hideMe(G.ui.altcanvas[x]);
61         }
62         hideMe(G.ui.common.loading);
63         unHideMe(G.ui.common.canvas_main);
64         try{G.ui.searchbar.text.focus();}catch(e){}
65 }
66
67 function swapCanvas(newNode) {
68         for( var x in G.ui.altcanvas ) 
69                 hideMe(G.ui.altcanvas[x]);
70
71         hideMe(G.ui.common.loading);
72         hideMe(G.ui.common.canvas_main);
73         unHideMe(newNode);
74 }
75
76 /* finds the name of the current page */
77 var currentPage = null;
78 function findCurrentPage() {
79         if(currentPage) return currentPage;
80
81         var pages = [];
82         for( var p in config.page ) pages.push(config.page[p]);
83         pages = pages.sort( function(a,b){ return - (a.length - b.length); } );
84
85         var path = location.pathname;
86         if(!path.match(/.*\.xml$/))
87                 path += "index.xml"; /* in case they go to  / */
88
89         var page = null;
90         for( var p in pages ) {
91                 if( path.indexOf(pages[p]) != -1)
92                         page = pages[p];
93         }
94
95         for( var p in config.page ) {
96                 if(config.page[p] == page) {
97                         currentPage = p;
98                         return p;
99                 }
100         }
101         return null;
102 }
103
104
105 /* sets all of the params values  ----------------------------- */
106 function initParams() {
107         var cgi = new CGI();    
108
109         /* handle the location var */
110         var org;
111         var loc = cgi.param(PARAM_LOCATION);
112         if( loc ) {
113                 org = findOrgUnit(loc);
114                 if(!org) org = findOrgUnitSN(loc);
115         } 
116         LOCATION        = (org) ? org.id() : null;
117
118         org = null;
119         loc = cgi.param(PARAM_ORIGLOC);
120         if( loc ) {
121                 org = findOrgUnit(loc);
122                 if(!org) org = findOrgUnitSN(loc);
123         }
124         ORIGLOC = (org) ? org.id() : null;
125
126
127         DEPTH = parseInt(cgi.param(PARAM_DEPTH));
128         if(isNaN(DEPTH)) DEPTH = null;
129
130
131         TERM            = cgi.param(PARAM_TERM);
132         STYPE           = cgi.param(PARAM_STYPE);
133         FORM            = cgi.param(PARAM_FORM);
134         //DEPTH         = parseInt(cgi.param(PARAM_DEPTH));
135         OFFSET  = parseInt(cgi.param(PARAM_OFFSET));
136         COUNT           = parseInt(cgi.param(PARAM_COUNT));
137         HITCOUNT        = parseInt(cgi.param(PARAM_HITCOUNT));
138         MRID            = parseInt(cgi.param(PARAM_MRID));
139         RID             = parseInt(cgi.param(PARAM_RID));
140         AUTHTIME        = parseInt(cgi.param(PARAM_AUTHTIME));
141         ADVTERM = cgi.param(PARAM_ADVTERM);
142         ADVTYPE = cgi.param(PARAM_ADVTYPE);
143         RTYPE           = cgi.param(PARAM_RTYPE);
144         SORT            = cgi.param(PARAM_SORT);
145         SORT_DIR        = cgi.param(PARAM_SORT_DIR);
146         DEBUG           = cgi.param(PARAM_DEBUG);
147         CALLNUM = cgi.param(PARAM_CN);
148         LITFORM = cgi.param(PARAM_LITFORM);
149         ITEMFORM        = cgi.param(PARAM_ITEMFORM);
150         ITEMTYPE        = cgi.param(PARAM_ITEMTYPE);
151         AUDIENCE        = cgi.param(PARAM_AUDIENCE);
152         SEARCHES = cgi.param(PARAM_SEARCHES);
153         LANGUAGE        = cgi.param(PARAM_LANGUAGE);
154         TFORM           = cgi.param(PARAM_TFORM);
155         RDEPTH  = cgi.param(PARAM_RDEPTH);
156     AVAIL   = cgi.param(PARAM_AVAIL);
157
158         /* set up some sane defaults */
159         //if(isNaN(DEPTH))      DEPTH           = 0;
160         if(isNaN(RDEPTH))       RDEPTH  = 0;
161         if(isNaN(OFFSET))       OFFSET  = 0;
162         if(isNaN(COUNT))        COUNT           = 10;
163         if(isNaN(HITCOUNT))     HITCOUNT        = 0;
164         if(isNaN(MRID))         MRID            = 0;
165         if(isNaN(RID))          RID             = 0;
166         if(isNaN(ORIGLOC))      ORIGLOC = 0; /* so we know it hasn't been set */
167         if(isNaN(AUTHTIME))     AUTHTIME        = 0;
168         if(ADVTERM==null)       ADVTERM = "";
169     if(isNaN(AVAIL))    AVAIL = 0;
170 }
171
172 function clearSearchParams() {
173         TERM        = null;
174         STYPE       = null;
175         FORM        = null;
176         OFFSET      = 0;
177         HITCOUNT    = 0;  
178         ADVTERM     = null;
179         ADVTYPE     = null;
180         MRID        = null;
181         RID         = null;
182         RTYPE       = null;
183         SORT        = null;
184         SORT_DIR    = null;
185         RLIST       = null;
186         CALLNUM     = null;
187         LITFORM     = null;
188         ITEMFORM    = null;
189         ITEMTYPE    = null;
190         AUDIENCE    = null;
191         SEARCHES    = null;
192         LANGUAGE    = null;
193         RDEPTH      = null;
194     AVAIL       = null;
195 }
196
197
198 function initCookies() {
199         FONTSIZE = "regular";
200         var font = cookieManager.read(COOKIE_FONT);
201         scaleFonts(font);
202         if(font) FONTSIZE = font;
203         SKIN = cookieManager.read(COOKIE_SKIN);
204 }
205
206 /* URL param accessors */
207 function getTerm(){return TERM;}
208 function getStype(){return STYPE;}
209 function getLocation(){return LOCATION;}
210 function getDepth(){return DEPTH;}
211 function getForm(){return FORM;}
212 function getTform(){return TFORM;}
213 function getOffset(){return OFFSET;}
214 function getDisplayCount(){return COUNT;}
215 function getHitCount(){return HITCOUNT;}
216 function getMrid(){return MRID;};
217 function getRid(){return RID;};
218 function getOrigLocation(){return ORIGLOC;}
219 function getAuthtime() { return AUTHTIME; }
220 function getSearchBarExtras(){return SBEXTRAS;}
221 function getFontSize(){return FONTSIZE;};
222 function getSkin(){return SKIN;};
223 function getAdvTerm(){return ADVTERM;}
224 function getAdvType(){return ADVTYPE;}
225 function getRtype(){return RTYPE;}
226 function getSort(){return SORT;}
227 function getSortDir(){return SORT_DIR;}
228 function getDebug(){return DEBUG;}
229 function getCallnumber() { return CALLNUM; }
230 function getLitForm() { return LITFORM; }
231 function getItemForm() { return ITEMFORM; }
232 function getItemType() { return ITEMTYPE; }
233 function getAudience() { return AUDIENCE; }
234 function getSearches() { return SEARCHES; }
235 function getLanguage() { return LANGUAGE; }
236 function getRdepth() { return RDEPTH; }
237 function getAvail() { return AVAIL; }
238
239
240 function findBasePath() {
241         var path = location.pathname;
242         if(!path.match(/.*\.xml$/)) path += "index.xml"; 
243         var idx = path.indexOf(config.page[findCurrentPage()]);
244         return path.substring(0, idx);
245 }
246
247 function findBaseURL(ssl) {
248         var path = findBasePath();
249         var proto = (ssl) ? "https:" : "http:";
250
251         /* strip port numbers.  This is necessary for browsers that
252         send an explicit  <host>:80, 443 - explicit ports
253         break links that need to change ports (e.g. http -> https) */
254         var h = location.host.replace(/:.*/,''); 
255
256         return proto + "//" + h + path;
257 }
258
259 /*
260 function buildISBNSrc(isbn) {
261         return "http://" + location.host + "/jackets/" + isbn;
262 }
263 */
264
265 function buildImageLink(name, ssl) {
266         return findBaseURL(ssl) + "../../../../images/" + name;
267 }
268
269 function buildExtrasLink(name, ssl) {
270         return findBaseURL(ssl) + "../../../../extras/" + name;
271 }
272
273 var consoleService;
274 function _debug(str) { 
275         try { dump('dbg: ' + str + '\n'); } catch(e) {} 
276
277         /* potentially useful, but usually just annoying */
278         /*
279         if(!IE) {
280                 if(!consoleService) {
281                         try {
282                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
283                                 this.consoleService = Components.classes['@mozilla.org/consoleservice;1']
284                                         .getService(Components.interfaces.nsIConsoleService);
285                         } catch(e) {}
286                 }
287         
288                 try {
289                         if(consoleService) {
290                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
291                                 consoleService.logStringMessage(str + '\n');
292                         }
293                 } catch(e){}
294         }
295         */
296 }
297
298 function  buildOPACLink(args, slim, ssl) {
299
300         if(!args) args = {};
301         var string = "";
302
303         if(!slim) {
304                 string = findBaseURL(ssl);
305                 if(args.page) string += config.page[args.page];
306                 else string += config.page[findCurrentPage()];
307         }
308
309         /* this may seem unnecessary.. safety precaution for now */
310         /*
311         if( args[PARAM_DEPTH] == null )
312                 args[PARAM_DEPTH] = getDepth();
313                 */
314
315         string += "?";
316
317         for( var x in args ) {
318                 var v = args[x];
319                 if(x == "page" || v == null || v == undefined || v+'' == 'NaN' ) continue;
320                 if(x == PARAM_OFFSET && v == 0) continue;
321                 if(x == PARAM_COUNT && v == 10) continue;
322                 if(x == PARAM_FORM && v == 'all' ) continue;
323                 if( instanceOf(v, Array) && v.length ) {
324                         for( var i = 0; i < v.length; i++ ) {
325                                 string += "&" + x + "=" + encodeURIComponent(v[i]);
326                         }
327                 } else {
328                         string += "&" + x + "=" + encodeURIComponent(v);
329                 }
330         }
331
332         if(getDebug())
333                 string += _appendParam(DEBUG,           PARAM_DEBUG, args, getDebug, string);
334         if(getOrigLocation() != 1) 
335                 string += _appendParam(ORIGLOC, PARAM_ORIGLOC, args, getOrigLocation, string);
336         if(getTerm()) 
337                 string += _appendParam(TERM,            PARAM_TERM, args, getTerm, string);
338         if(getStype()) 
339                 string += _appendParam(STYPE,           PARAM_STYPE, args, getStype, string);
340         if(getLocation() != 1) 
341                 string += _appendParam(LOCATION, PARAM_LOCATION, args, getLocation, string);
342         if(getDepth() != null) 
343                 string += _appendParam(DEPTH,           PARAM_DEPTH, args, getDepth, string);
344         if(getForm() && (getForm() != 'all') ) 
345                 string += _appendParam(FORM,            PARAM_FORM, args, getForm, string);
346         if(getTform() && (getTform() != 'all') ) 
347                 string += _appendParam(TFORM,           PARAM_TFORM, args, getTform, string);
348         if(getOffset() != 0) 
349                 string += _appendParam(OFFSET,  PARAM_OFFSET, args, getOffset, string);
350         if(getDisplayCount() != 10) 
351                 string += _appendParam(COUNT,           PARAM_COUNT, args, getDisplayCount, string);
352         if(getHitCount()) 
353                 string += _appendParam(HITCOUNT, PARAM_HITCOUNT, args, getHitCount, string);
354         if(getMrid())
355                 string += _appendParam(MRID,            PARAM_MRID, args, getMrid, string);
356         if(getRid())
357                 string += _appendParam(RID,             PARAM_RID, args, getRid, string);
358         if(getAuthtime())
359                 string += _appendParam(AUTHTIME,        PARAM_AUTHTIME, args, getAuthtime, string);
360         if(getAdvTerm())
361                 string += _appendParam(ADVTERM, PARAM_ADVTERM, args, getAdvTerm, string);
362         if(getAdvType())
363                 string += _appendParam(ADVTYPE, PARAM_ADVTYPE, args, getAdvType, string);
364         if(getRtype())
365                 string += _appendParam(RTYPE,           PARAM_RTYPE, args, getRtype, string);
366         if(getItemForm())
367                 string += _appendParam(ITEMFORM,        PARAM_ITEMFORM, args, getItemForm, string);
368         if(getItemType())
369                 string += _appendParam(ITEMTYPE,        PARAM_ITEMTYPE, args, getItemType, string);
370         if(getLitForm())
371                 string += _appendParam(LITFORM, PARAM_LITFORM, args, getLitForm, string);
372         if(getAudience())
373                 string += _appendParam(AUDIENCE,        PARAM_AUDIENCE, args, getAudience, string);
374         if(getSearches())
375                 string += _appendParam(SEARCHES,        PARAM_SEARCHES, args, getSearches, string);
376         if(getLanguage())
377                 string += _appendParam(LANGUAGE,        PARAM_LANGUAGE, args, getLanguage, string);
378         if(getRdepth() != null)
379                 string += _appendParam(RDEPTH,  PARAM_RDEPTH, args, getRdepth, string);
380         if(getSort() != null)
381                 string += _appendParam(SORT,    PARAM_SORT, args, getSort, string);
382         if(getSortDir() != null)
383                 string += _appendParam(SORT_DIR,        PARAM_SORT_DIR, args, getSortDir, string);
384         if(getAvail())
385                 string += _appendParam(AVAIL, PARAM_AVAIL, args, getAvail, string);
386
387         return string.replace(/\&$/,'').replace(/\?\&/,"?");    
388 }
389
390 var xx = 1;
391 function _appendParam( fieldVar, fieldName, overrideArgs, getFunc, string ) {
392
393         var ret = "";
394
395         if(     fieldVar != null && 
396                         (fieldVar +'' != 'NaN') && 
397                         overrideArgs[fieldName] == null &&
398                         getFunc() != null &&
399                         getFunc()+'' != '' ) {
400
401                 ret = "&" + fieldName + "=" + encodeURIComponent(getFunc());
402         }
403
404         return ret;
405 }
406
407 /* ----------------------------------------------------------------------- */
408 function cleanISBN(isbn) {
409    if(isbn) {
410       isbn = isbn.toString().replace(/^\s+/,"");
411       var idx = isbn.indexOf(" ");
412       if(idx > -1) { isbn = isbn.substring(0, idx); }
413    } else isbn = "";
414    return isbn;
415 }       
416
417
418 /* builds a link that goes to the title listings for a metarecord */
419 function buildTitleLink(rec, link) {
420         if(!rec) return;
421         link.appendChild(text(normalize(truncate(rec.title(), 65))));
422         var args = {};
423         args.page = RRESULT;
424         args[PARAM_OFFSET] = 0;
425         args[PARAM_MRID] = rec.doc_id();
426         args[PARAM_RTYPE] = RTYPE_MRID;
427         link.setAttribute("href", buildOPACLink(args));
428 }
429
430 function buildTitleDetailLink(rec, link) {
431         if(!rec) return;
432         link.appendChild(text(normalize(truncate(rec.title(), 65))));
433         var args = {};
434         args.page = RDETAIL;
435         //args[PARAM_OFFSET] = 0;
436         args[PARAM_RID] = rec.doc_id();
437         link.setAttribute("href", buildOPACLink(args));
438 }
439
440 /* 'type' is one of STYPE_AUTHOR, STYPE_SUBJECT, ... found in config.js 
441         'trunc' is the number of characters to show in the string, defaults to 65 */
442 function buildSearchLink(type, string, linknode, trunc) {
443         if(!trunc) trunc = 65;
444         var args = {};
445         if( SHOW_MR_DEFAULT) {
446                 args.page = MRESULT;
447         } else {
448                 args.page = RRESULT;
449                 args[PARAM_RTYPE] = type;
450         }
451         args[PARAM_OFFSET] = 0;
452         args[PARAM_TERM] = string;
453         args[PARAM_STYPE] = type;
454         linknode.appendChild(text(normalize(truncate(string, trunc))));
455         linknode.setAttribute("href", buildOPACLink(args));
456 }
457
458 function setSessionCookie(ses) {
459         cookieManager.write(COOKIE_SES, ses, -1);
460 }
461
462
463
464 /* ----------------------------------------------------------------------- */
465 /* user session handling */
466 /* ----------------------------------------------------------------------- */
467 /* session is the login session.  If no session is provided, we attempt
468         to find one in the cookies.  If 'force' is true we retrieve the 
469         user from the server even if there is already a global user present.
470         if ses != G.user.session, we also force a grab */
471 function grabUser(ses, force) {
472
473         if(!ses && isXUL()) {
474                 stash = fetchXULStash();
475                 ses = stash.session.key
476                 _debug("stash auth token = " + ses);
477         }
478
479         if(!ses) {
480                 ses = cookieManager.read(COOKIE_SES);
481                 /* https cookies don't show up in http servers.. */
482         }
483
484         if(!ses) return false;
485
486         if(!force) 
487                 if(G.user && G.user.session == ses)
488                         return G.user;
489
490         /* first make sure the session is valid */
491         var request = new Request(FETCH_SESSION, ses, 1 );
492         request.request.alertEvent = false;
493         request.send(true);
494         var user = request.result();
495
496         if(!user) {
497                 doLogout();
498                 return false; /* unable to grab the session */
499         }
500
501         if( !(typeof user == 'object' && user._isfieldmapper) ) {
502                 doLogout();
503                 return false;
504         }
505
506         G.user = user;
507         G.user.fleshed = false;
508         G.user.session = ses;
509         setSessionCookie(ses);
510
511         grabUserPrefs();
512         if(G.user.prefs['opac.hits_per_page'])
513                 COUNT = parseInt(G.user.prefs['opac.hits_per_page']);
514
515         if(G.user.prefs[PREF_DEF_FONT]) 
516                 setFontSize(G.user.prefs[PREF_DEF_FONT]);
517
518         var at = getAuthtime();
519         //if(isXUL()) at = xulG['authtime'];
520
521         if(at && !isXUL()) new AuthTimer(at).run(); 
522         return G.user;
523 }
524
525
526 /* sets the 'prefs' field of the user object to their preferences 
527         and returns the preferences */
528 function grabUserPrefs(user, force) {
529         if(user == null) user = G.user;
530         if(!force && user.prefs) return user.prefs;     
531         var req = new Request(FETCH_USER_PREFS, user.session, user.id());
532         req.send(true);
533         user.prefs = req.result();
534         return user.prefs;
535 }
536
537 function grabFleshedUser() {
538
539         if(!G.user || !G.user.session) {
540                 grabUser();     
541                 if(!G.user || !G.user.session) return null;
542         }
543
544         if(G.user.fleshed) return G.user;
545
546    var req = new Request(FETCH_FLESHED_USER, G.user.session);
547         req.send(true);
548
549         G.user = req.result();
550
551         if(!G.user || G.user.length == 0) { 
552                 G.user = null; return false; 
553                 cookieManager.write(COOKIE_SES,"");
554         }
555
556         G.user.session = ses;
557         G.user.fleshed = true;
558
559         setSessionCookie(ses);
560         return G.user;
561 }
562
563 function checkUserSkin(new_skin) {
564
565         return; /* XXX do some debugging with this... */
566
567         var user_skin = getSkin();
568         var cur_skin = grabSkinFromURL();
569
570         if(new_skin) user_skin = new_skin;
571
572         if(!user_skin) {
573
574                 if(grabUser()) {
575                         if(grabUserPrefs()) {
576                                 user_skin = G.user.prefs["opac.skin"];
577                                 cookieManager.write( COOKIE_SKIN, user_skin, '+1y' );
578                         }
579                 }
580         }
581
582         if(!user_skin) return;
583
584         if( cur_skin != user_skin ) {
585                 var url = buildOPACLink();
586                 goTo(url.replace(cur_skin, user_skin));
587         }
588 }
589
590 function updateUserSetting(setting, value, user) {
591         if(user == null) user = G.user;
592         var a = {};
593         a[setting] = value;
594         var req = new Request( UPDATE_USER_PREFS, user.session, a );
595         req.send(true);
596         return req.result();
597 }
598
599 function commitUserPrefs() {
600         var req = new Request( 
601                 UPDATE_USER_PREFS, G.user.session, null, G.user.prefs );
602         req.send(true);
603         return req.result();
604 }
605
606 function grabSkinFromURL() {
607         var path = findBasePath();
608         path = path.replace("/xml/", "");
609         var skin = "";
610         for( var i = path.length - 1; i >= 0; i-- ) {
611                 var ch = path.charAt(i);
612                 if(ch == "/") break;
613                 skin += ch;
614         }
615
616         var skin2 = "";
617         for( i = skin.length - 1; i >= 0; i--)
618                 skin2 += skin.charAt(i);
619
620         return skin2;
621 }
622
623
624 /* returns a fleshed G.user on success, false on failure */
625 function doLogin(suppressEvents) {
626
627         abortAllRequests();
628
629         var uname = G.ui.login.username.value;
630         var passwd = G.ui.login.password.value; 
631
632         var init_request = new Request( LOGIN_INIT, uname );
633    init_request.send(true);
634    var seed = init_request.result();
635
636    if( ! seed || seed == '0') {
637       alert( "Error Communicating with Authentication Server" );
638       return null;
639    }
640
641         var args = {
642                 password : hex_md5(seed + hex_md5(passwd)), 
643                 type            : "opac", 
644                 org             : getOrigLocation()
645         };
646
647         if( uname.match(REGEX_BARCODE) ) args.barcode = uname; /* make this better */
648         else args.username = uname;
649
650    var auth_request = new Request( LOGIN_COMPLETE, args );
651
652         auth_request.request.alertEvent = false;
653    auth_request.send(true);
654    var auth_result = auth_request.result();
655
656         if(!auth_result) {
657                 alertId('patron_login_failed');
658                 return null;
659         }
660
661         if( checkILSEvent(auth_result) ) {
662
663                 if( auth_result.textcode == 'PATRON_INACTIVE' ) {
664                         alertId('patron_inactive_alert');
665                         return;
666                 }
667
668                 if( auth_result.textcode == 'PATRON_CARD_INACTIVE' ) {
669                         alertId('patron_card_inactive_alert');
670                         return;
671                 }
672
673                 if( auth_result.textcode == 'LOGIN_FAILED' || 
674                                 auth_result.textcode == 'PERM_FAILURE' ) {
675                         alertId('patron_login_failed');
676                         return;
677                 }
678         }
679
680
681         AUTHTIME = parseInt(auth_result.payload.authtime);
682         var u = grabUser(auth_result.payload.authtoken, true);
683         if(u && ! suppressEvents) 
684                 runEvt( "common", "locationChanged", u.ws_ou(), findOrgDepth(u.ws_ou()) );
685
686         checkUserSkin();
687
688         return u;
689 }
690
691 function doLogout(noredirect) {
692
693         /* cancel everything else */
694         abortAllRequests();
695
696         /* be nice and delete the session from the server */
697         if(G.user && G.user.session) { 
698                 var req = new Request(LOGIN_DELETE, G.user.session);
699       req.send(true);
700                 try { req.result(); } catch(E){}
701     }
702
703         G.user = null;
704
705         /* remove any cached data */
706         //cookieManager.remove(COOKIE_IDS);
707         //cookieManager.remove(COOKIE_SRIDS);
708         cookieManager.remove(COOKIE_RIDS);
709         cookieManager.remove(COOKIE_SES);
710         cookieManager.remove(COOKIE_SKIN);
711
712         checkUserSkin("default");
713         COUNT = 10;
714
715
716         var args = {};
717         args[PARAM_TERM] = "";
718         args[PARAM_LOCATION] = getOrigLocation();
719         args[PARAM_DEPTH] = findOrgDepth(getOrigLocation());
720         args.page = "home";
721
722         
723         var nored = false;
724         try{ if(isFrontPage) nored = true; } catch(e){nored = false;}
725         if(!nored) goTo(buildOPACLink(args));
726 }
727
728
729 function hideMe(obj) { addCSSClass(obj, config.css.hide_me); } 
730 function unHideMe(obj) { removeCSSClass(obj, config.css.hide_me); }
731
732
733 /* ----------------------------------------------------------------------- */
734 /* build the org tree */
735 /* ----------------------------------------------------------------------- */
736 function drawOrgTree() {
737         //setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 10 );
738         setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 1 );
739 }
740         
741 var orgTreeSelector;
742 function buildOrgSelector(node) {
743         var tree = new SlimTree(node,'orgTreeSelector');
744         orgTreeSelector = tree;
745         for( var i in orgArraySearcher ) { 
746                 var node = orgArraySearcher[i];
747                 if( node == null ) continue;
748         if(!isXUL() && !isTrue(node.opac_visible())) continue; 
749                 if(node.parent_ou() == null)
750                         tree.addNode(node.id(), -1, node.name(), 
751                                 "javascript:orgSelect(" + node.id() + ");", node.name());
752                 else {
753                         tree.addNode(node.id(), node.parent_ou(), node.name(), 
754                                 "javascript:orgSelect(" + node.id() + ");", node.name());
755                 }
756         }
757         hideMe($('org_loading_div'));
758         unHideMe($('org_selector_tip'));
759         return tree;
760 }
761
762 function orgSelect(id) {
763         showCanvas();
764         runEvt("common", "locationChanged", id, findOrgDepth(id) );
765
766         removeChildren(G.ui.common.now_searching);
767         G.ui.common.now_searching.appendChild(text(findOrgUnit(id).name()));
768 }
769
770 function setFontSize(size) {
771         scaleFonts(size);
772         cookieManager.write(COOKIE_FONT, size, '+1y');
773 }
774
775 var resourceFormats = [
776    "text",
777    "moving image",
778    "sound recording", "software, multimedia",
779    "still image",
780    "cartographic",
781    "mixed material",
782    "notated music",
783    "three dimensional object" ];
784
785
786 function modsFormatToMARC(format) {
787    switch(format) {
788       case "text":
789          return "at";
790       case "moving image":
791          return "g";
792       case "sound recording":
793          return "ij";
794       case "sound recording-nonmusical":
795          return "i";
796       case "sound recording-musical":
797          return "j";
798       case "software, multimedia":
799          return "m";
800       case "still image":
801          return "k";
802       case "cartographic":
803          return "ef";
804       case "mixed material":
805          return "op";
806       case "notated music":
807          return "cd";
808       case "three dimensional object":
809          return "r";
810    }
811    return "at";
812 }
813
814
815 function MARCFormatToMods(format) {
816    switch(format) {
817       case "a":
818       case "t":
819          return "text";
820       case "g":
821          return "moving image";
822       case "i":
823          return "sound recording-nonmusical";
824       case "j":
825          return "sound recording-musical";
826       case "m":
827          return "software, multimedia";
828       case "k":
829          return "still image";
830       case "e":
831       case "f":
832          return "cartographic";
833       case "o":
834       case "p":
835          return "mixed material";
836       case "c":
837       case "d":
838          return "notated music";
839       case "r":
840          return "three dimensional object";
841    }
842    return "text";
843 }
844
845 function MARCTypeToFriendly(format) {
846         var words = $('format_words');
847         switch(format) {
848                 case 'a' :
849                 case 't' : return $n(words, 'at').innerHTML;
850                 default:
851                         var node = $n(words,format);
852                         if( node ) return node.innerHTML;
853         }
854         return "";
855 }
856
857 function setResourcePic( img, resource ) {
858         img.setAttribute( "src", "../../../../images/tor/" + resource + ".jpg");
859         img.title = resource;
860 }
861
862
863
864 function msg( text ) {
865         try { alert( text ); } catch(e) {}
866 }
867
868 function findRecord(id,type) {
869         try {
870                 for( var i = 0; i != recordsCache.length; i++ ) {
871                         var rec = recordsCache[i];
872                         if( rec && rec.doc_id() == id ) return rec;
873                 }
874         } catch(E){}
875         var meth = FETCH_RMODS
876         if(type == 'M') meth = FETCH_MRMODS;
877         var req = new Request(meth, id);
878         req.request.alertEvent = false;
879         req.send(true);
880         var res = req.result();
881         if( checkILSEvent(res) ) return null; 
882         return res;
883 }
884
885 function Timer(name, node){
886         this.name = name;
887         this.count = 1;
888         this.node = node;
889 }
890 Timer.prototype.start = 
891         function(){_timerRun(this.name);}
892 Timer.prototype.stop = 
893         function(){this.done = true;}
894 function _timerRun(tname) {
895         var _t;
896         eval('_t='+tname);
897         if(_t.done) return;
898         if(_t.count > 100) return;
899         var str = ' . ';
900         if( (_t.count % 5) == 0 ) 
901                 str = _t.count / 5;
902         _t.node.appendChild(text(str));
903         setTimeout("_timerRun('"+tname+"');", 200);
904         _t.count++;
905 }
906
907 function checkILSEvent(obj) {
908         if( obj && obj.ilsevent != null && obj.ilsevent != 0 )
909                 return parseInt(obj.ilsevent);
910         return null;
911 }
912
913
914 function alertILSEvent(evt, msg) {
915    if(!msg) msg = "";
916         if(msg)
917                 alert(msg +'\n' + evt.textcode + '\n' + evt.desc );
918         else 
919                 alert(evt.textcode + '\n' + evt.desc );
920 }
921
922
923 var __authTimer;
924 function AuthTimer(time) { 
925         this.time = (time - LOGOUT_WARNING_TIME) * 1000; 
926         if(__authTimer) 
927                 try {clearTimeout(__authTimer.id)} catch(e){}
928         __authTimer = this;
929 }
930
931 AuthTimer.prototype.run = function() {
932         this.id = setTimeout('_authTimerAlert()', this.time);
933 }
934
935 function _authTimerAlert() {
936         alert( $('auth_session_expiring').innerHTML );
937         if(!grabUser(null, true)) doLogout();
938 }
939
940
941 function grabUserByBarcode( authtoken, barcode ) {
942         var req = new Request( FETCH_USER_BYBARCODE, authtoken, barcode );
943         req.send(true);
944         return req.result();
945 }
946
947
948 function goHome() {
949         goTo(buildOPACLink({page:HOME}));
950 }
951
952
953 function buildOrgSel(selector, org, offset) {
954         insertSelectorVal( selector, -1, 
955                 org.name(), org.id(), null, findOrgDepth(org) - offset );
956         for( var c in org.children() )
957                 buildOrgSel( selector, org.children()[c], offset);
958 }
959
960
961 function parseForm(form) {
962         if(!form) return {};
963
964         var it = form.replace(/-\w+$/,"");
965         var itf = null;
966         var item_form;
967         var item_type;
968
969         if(form.match(/-/)) itf = form.replace(/^\w+-/,"");
970
971         if(it) {
972                 item_type = [];
973                 for( var i = 0; i < it.length; i++ ) 
974                         item_type.push( it.charAt(i) );
975         }
976
977         if(itf) {
978                 item_form = [];
979                 for( var i = 0; i < itf.length; i++ ) 
980                         item_form.push( itf.charAt(i) );
981         }
982
983         return {item_type: item_type, item_form:item_form};
984 }
985
986
987 function isTrue(x) { return ( x && x != "0" && !(x+'').match(/^f$/i) ); }
988
989 function fetchPermOrgs() {
990         var a = []; /* why does arguments come accross as an object and not an array? */
991         for( var i = 0; i < arguments.length; i++ ) 
992                 a.push(arguments[i])
993
994         var preq = new Request(FETCH_HIGHEST_PERM_ORG, 
995                 G.user.session, G.user.id(), a );
996         preq.send(true);
997         return preq.result();
998 }
999
1000
1001 function print_tabs(t) {
1002         var r = '';
1003         for (var j = 0; j < t; j++ ) { r = r + "  "; }
1004         return r;
1005 }
1006 function formatJSON(s) {
1007         var r = ''; var t = 0;
1008         for (var i in s) {
1009                 if (s[i] == '{' || s[i] == '[' ) {
1010                         r = r + s[i] + "\n" + print_tabs(++t);
1011                 } else if (s[i] == '}' || s[i] == ']') {
1012                         t--; r = r + "\n" + print_tabs(t) + s[i];
1013                 } else if (s[i] == ',') {
1014                         r = r + s[i] + "\n" + print_tabs(t);
1015                 } else {
1016                         r = r + s[i];
1017                 }
1018         }
1019         return r;
1020 }