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