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