]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/opac_utils.js
Patch from Jeff Godin to make holds placed by staff respect the patron's notification...
[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 in pages ) {
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 function  buildOPACLink(args, slim, ssl) {
333
334         if(!args) args = {};
335         var string = "";
336
337         if(!slim) {
338                 string = findBaseURL(ssl);
339                 if(args.page) string += config.page[args.page];
340                 else string += config.page[findCurrentPage()];
341         }
342
343         /* this may seem unnecessary.. safety precaution for now */
344         /*
345         if( args[PARAM_DEPTH] == null )
346                 args[PARAM_DEPTH] = getDepth();
347                 */
348
349         string += "?";
350
351         for( var x in args ) {
352                 var v = args[x];
353                 if(x == "page" || v == null || v == undefined || v+'' == 'NaN' ) continue;
354                 if(x == PARAM_OFFSET && v == 0) continue;
355                 if(x == PARAM_COUNT && v == 10) continue;
356                 if(x == PARAM_FORM && v == 'all' ) continue;
357                 if( instanceOf(v, Array) && v.length ) {
358                         for( var i = 0; i < v.length; i++ ) {
359                                 string += "&" + x + "=" + encodeURIComponent(v[i]);
360                         }
361                 } else {
362                         string += "&" + x + "=" + encodeURIComponent(v);
363                 }
364         }
365
366         if(getDebug())
367                 string += _appendParam(DEBUG,           PARAM_DEBUG, args, getDebug, string);
368         if(getOrigLocation() != 1) 
369                 string += _appendParam(ORIGLOC, PARAM_ORIGLOC, args, getOrigLocation, string);
370         if(getTerm()) 
371                 string += _appendParam(TERM,            PARAM_TERM, args, getTerm, string);
372         if(getStype()) 
373                 string += _appendParam(STYPE,           PARAM_STYPE, args, getStype, string);
374         if(getLocation() != 1) 
375                 string += _appendParam(LOCATION, PARAM_LOCATION, args, getLocation, string);
376         if(getLasso() != null) 
377                 string += _appendParam(LASSO, PARAM_LASSO, args, getLasso, string);
378         if(getDepth() != null) 
379                 string += _appendParam(DEPTH,           PARAM_DEPTH, args, getDepth, string);
380         if(getForm() && (getForm() != 'all') ) 
381                 string += _appendParam(FORM,            PARAM_FORM, args, getForm, string);
382         if(getTform() && (getTform() != 'all') ) 
383                 string += _appendParam(TFORM,           PARAM_TFORM, args, getTform, string);
384         if(getOffset() != 0) 
385                 string += _appendParam(OFFSET,  PARAM_OFFSET, args, getOffset, string);
386         if(getDisplayCount() != 10) 
387                 string += _appendParam(COUNT,           PARAM_COUNT, args, getDisplayCount, string);
388         if(getHitCount()) 
389                 string += _appendParam(HITCOUNT, PARAM_HITCOUNT, args, getHitCount, string);
390         if(getMrid())
391                 string += _appendParam(MRID,            PARAM_MRID, args, getMrid, string);
392         if(getRid())
393                 string += _appendParam(RID,             PARAM_RID, args, getRid, string);
394         if(getAuthtime())
395                 string += _appendParam(AUTHTIME,        PARAM_AUTHTIME, args, getAuthtime, string);
396         if(getAdvTerm())
397                 string += _appendParam(ADVTERM, PARAM_ADVTERM, args, getAdvTerm, string);
398         if(getAdvType())
399                 string += _appendParam(ADVTYPE, PARAM_ADVTYPE, args, getAdvType, string);
400         if(getRtype())
401                 string += _appendParam(RTYPE,           PARAM_RTYPE, args, getRtype, string);
402         if(getItemForm())
403                 string += _appendParam(ITEMFORM,        PARAM_ITEMFORM, args, getItemForm, string);
404         if(getItemType())
405                 string += _appendParam(ITEMTYPE,        PARAM_ITEMTYPE, args, getItemType, string);
406         if(getBibLevel())
407                 string += _appendParam(BIBLEVEL,        PARAM_BIBLEVEL, args, getBibLevel, string);
408         if(getLitForm())
409                 string += _appendParam(LITFORM, PARAM_LITFORM, args, getLitForm, string);
410         if(getAudience())
411                 string += _appendParam(AUDIENCE,        PARAM_AUDIENCE, args, getAudience, string);
412         if(getSearches())
413                 string += _appendParam(SEARCHES,        PARAM_SEARCHES, args, getSearches, string);
414         if(getLanguage())
415                 string += _appendParam(LANGUAGE,        PARAM_LANGUAGE, args, getLanguage, string);
416         if(getRdepth() != null)
417                 string += _appendParam(RDEPTH,  PARAM_RDEPTH, args, getRdepth, string);
418         if(getSort() != null)
419                 string += _appendParam(SORT,    PARAM_SORT, args, getSort, string);
420         if(getSortDir() != null)
421                 string += _appendParam(SORT_DIR,        PARAM_SORT_DIR, args, getSortDir, string);
422         if(getAvail())
423                 string += _appendParam(AVAIL, PARAM_AVAIL, args, getAvail, string);
424         if(getCopyLocs())
425                 string += _appendParam(COPYLOCS, PARAM_COPYLOCS, args, getCopyLocs, string);
426     if(getPubdBefore())
427                 string += _appendParam(PUBD_BEFORE, PARAM_PUBD_BEFORE, args, getPubdBefore, string);
428     if(getPubdAfter())
429                 string += _appendParam(PUBD_AFTER, PARAM_PUBD_AFTER, args, getPubdAfter, string);
430     if(getPubdBetween())
431                 string += _appendParam(PUBD_BETWEEN, PARAM_PUBD_BETWEEN, args, getPubdBetween, string);
432     if(getPubdDuring())
433                 string += _appendParam(PUBD_DURING, PARAM_PUBD_DURING, args, getPubdDuring, string);
434
435
436         return string.replace(/\&$/,'').replace(/\?\&/,"?");    
437 }
438
439 var xx = 1;
440 function _appendParam( fieldVar, fieldName, overrideArgs, getFunc, string ) {
441
442         var ret = "";
443
444         if(     fieldVar != null && 
445                         (fieldVar +'' != 'NaN') && 
446                         overrideArgs[fieldName] == null &&
447                         getFunc() != null &&
448                         getFunc()+'' != '' ) {
449
450                 ret = "&" + fieldName + "=" + encodeURIComponent(getFunc());
451         }
452
453         return ret;
454 }
455
456 /* ----------------------------------------------------------------------- */
457 function cleanISBN(isbn) {
458    if(isbn) {
459       isbn = isbn.toString().replace(/^\s+/,"");
460       var idx = isbn.indexOf(" ");
461       if(idx > -1) { isbn = isbn.substring(0, idx); }
462    } else isbn = "";
463    return isbn;
464 }       
465
466
467 /* builds a link that goes to the title listings for a metarecord */
468 function buildTitleLink(rec, link) {
469         if(!rec) return;
470         link.appendChild(text(normalize(truncate(rec.title(), 65))));
471         var args = {};
472         args.page = RRESULT;
473         args[PARAM_OFFSET] = 0;
474         args[PARAM_MRID] = rec.doc_id();
475         args[PARAM_RTYPE] = RTYPE_MRID;
476     var linkText = link.innerHTML; // IE
477         link.setAttribute("href", buildOPACLink(args));
478     link.innerHTML = linkText; // IE
479 }
480
481 function buildTitleDetailLink(rec, link) {
482         if(!rec) return;
483         link.appendChild(text(normalize(truncate(rec.title(), 65))));
484         var args = {};
485         args.page = RDETAIL;
486         args[PARAM_RID] = rec.doc_id();
487     // in IE, if the link text contains a '@', it replaces the innerHTML text 
488     // with the value of the href attribute.  Wait, what?  Yes.  Capture the
489     // innerHTML and put it back into place after the href is set
490     var linkText = link.innerHTML; // IE
491         link.setAttribute("href", buildOPACLink(args));
492     link.innerHTML = linkText; // IE
493 }
494
495 /* 'type' is one of STYPE_AUTHOR, STYPE_SUBJECT, ... found in config.js 
496         'trunc' is the number of characters to show in the string, defaults to 65 */
497 function buildSearchLink(type, string, linknode, trunc) {
498         if(!trunc) trunc = 65;
499         var args = {};
500         if( SHOW_MR_DEFAULT) {
501                 args.page = MRESULT;
502         } else {
503                 args.page = RRESULT;
504                 args[PARAM_RTYPE] = type;
505         }
506         args[PARAM_OFFSET] = 0;
507         args[PARAM_TERM] = string;
508         args[PARAM_STYPE] = type;
509         linknode.appendChild(text(normalize(truncate(string, trunc))));
510         linknode.setAttribute("href", buildOPACLink(args));
511 }
512
513 function setSessionCookie(ses) {
514         cookieManager.write(COOKIE_SES, ses, -1);
515 }
516
517
518
519 /* ----------------------------------------------------------------------- */
520 /* user session handling */
521 /* ----------------------------------------------------------------------- */
522 /* session is the login session.  If no session is provided, we attempt
523         to find one in the cookies.  If 'force' is true we retrieve the 
524         user from the server even if there is already a global user present.
525         if ses != G.user.session, we also force a grab */
526 function grabUser(ses, force) {
527
528         if(!ses && isXUL()) {
529                 stash = fetchXULStash();
530                 ses = stash.session.key
531                 _debug("stash auth token = " + ses);
532         }
533
534         if(!ses) {
535                 ses = cookieManager.read(COOKIE_SES);
536                 /* https cookies don't show up in http servers.. */
537         }
538
539         if(!ses) return false;
540
541         if(!force) 
542                 if(G.user && G.user.session == ses)
543                         return G.user;
544
545         /* first make sure the session is valid */
546         var request = new Request(FETCH_SESSION, ses, 1 );
547         request.request.alertEvent = false;
548         request.send(true);
549         var user = request.result();
550
551         if(!user) {
552                 doLogout();
553                 return false; /* unable to grab the session */
554         }
555
556         if( !(typeof user == 'object' && user._isfieldmapper) ) {
557                 doLogout();
558                 return false;
559         }
560
561         G.user = user;
562         G.user.fleshed = false;
563         G.user.session = ses;
564         setSessionCookie(ses);
565
566         grabUserPrefs();
567         if(G.user.prefs['opac.hits_per_page'])
568                 COUNT = parseInt(G.user.prefs['opac.hits_per_page']);
569
570         if(G.user.prefs[PREF_DEF_FONT]) 
571                 setFontSize(G.user.prefs[PREF_DEF_FONT]);
572
573         var at = getAuthtime();
574         //if(isXUL()) at = xulG['authtime'];
575
576         if(at && !isXUL()) new AuthTimer(at).run(); 
577         return G.user;
578 }
579
580
581 /* sets the 'prefs' field of the user object to their preferences 
582         and returns the preferences */
583 function grabUserPrefs(user, force) {
584         if(user == null) user = G.user;
585         if(!force && user.prefs) return user.prefs;     
586         var req = new Request(FETCH_USER_PREFS, G.user.session, user.id());
587         req.send(true);
588         user.prefs = req.result();
589         return user.prefs;
590 }
591
592 function grabFleshedUser() {
593
594         if(!G.user || !G.user.session) {
595                 grabUser();     
596                 if(!G.user || !G.user.session) return null;
597         }
598
599         if(G.user.fleshed) return G.user;
600
601    var req = new Request(FETCH_FLESHED_USER, G.user.session);
602         req.send(true);
603
604         G.user = req.result();
605
606         if(!G.user || G.user.length == 0) { 
607                 G.user = null; return false; 
608                 cookieManager.write(COOKIE_SES,"");
609         }
610
611         G.user.session = ses;
612         G.user.fleshed = true;
613
614         setSessionCookie(ses);
615         return G.user;
616 }
617
618 function checkUserSkin(new_skin) {
619
620         return; /* XXX do some debugging with this... */
621
622         var user_skin = getSkin();
623         var cur_skin = grabSkinFromURL();
624
625         if(new_skin) user_skin = new_skin;
626
627         if(!user_skin) {
628
629                 if(grabUser()) {
630                         if(grabUserPrefs()) {
631                                 user_skin = G.user.prefs["opac.skin"];
632                                 cookieManager.write( COOKIE_SKIN, user_skin, '+1y' );
633                         }
634                 }
635         }
636
637         if(!user_skin) return;
638
639         if( cur_skin != user_skin ) {
640                 var url = buildOPACLink();
641                 goTo(url.replace(cur_skin, user_skin));
642         }
643 }
644
645 function updateUserSetting(setting, value, user) {
646         if(user == null) user = G.user;
647         var a = {};
648         a[setting] = value;
649         var req = new Request( UPDATE_USER_PREFS, user.session, a );
650         req.send(true);
651         return req.result();
652 }
653
654 function commitUserPrefs() {
655         var req = new Request( 
656                 UPDATE_USER_PREFS, G.user.session, null, G.user.prefs );
657         req.send(true);
658         return req.result();
659 }
660
661 function grabSkinFromURL() {
662         var path = findBasePath();
663         path = path.replace("/xml/", "");
664         var skin = "";
665         for( var i = path.length - 1; i >= 0; i-- ) {
666                 var ch = path.charAt(i);
667                 if(ch == "/") break;
668                 skin += ch;
669         }
670
671         var skin2 = "";
672         for( i = skin.length - 1; i >= 0; i--)
673                 skin2 += skin.charAt(i);
674
675         return skin2;
676 }
677
678
679 /* returns a fleshed G.user on success, false on failure */
680 function doLogin(suppressEvents) {
681
682         abortAllRequests();
683
684         var uname = G.ui.login.username.value;
685         var passwd = G.ui.login.password.value; 
686
687         var init_request = new Request( LOGIN_INIT, uname );
688    init_request.send(true);
689    var seed = init_request.result();
690
691    if( ! seed || seed == '0') {
692       alert( "Error Communicating with Authentication Server" );
693       return null;
694    }
695
696         var args = {
697                 password : hex_md5(seed + hex_md5(passwd)), 
698                 type            : "opac", 
699                 org             : getOrigLocation()
700         };
701
702     r = fetchOrgSettingDefault(globalOrgTree.id(), 'opac.barcode_regex');
703     if(r) REGEX_BARCODE = new RegExp(r);
704     
705     if( uname.match(REGEX_BARCODE) ) args.barcode = uname;
706         else args.username = uname;
707
708    var auth_request = new Request( LOGIN_COMPLETE, args );
709
710         auth_request.request.alertEvent = false;
711    auth_request.send(true);
712    var auth_result = auth_request.result();
713
714         if(!auth_result) {
715                 alertId('patron_login_failed');
716                 return null;
717         }
718
719         if( checkILSEvent(auth_result) ) {
720
721                 if( auth_result.textcode == 'PATRON_INACTIVE' ) {
722                         alertId('patron_inactive_alert');
723                         return;
724                 }
725
726                 if( auth_result.textcode == 'PATRON_CARD_INACTIVE' ) {
727                         alertId('patron_card_inactive_alert');
728                         return;
729                 }
730
731                 if( auth_result.textcode == 'LOGIN_FAILED' || 
732                                 auth_result.textcode == 'PERM_FAILURE' ) {
733                         alertId('patron_login_failed');
734                         return;
735                 }
736         }
737
738
739         AUTHTIME = parseInt(auth_result.payload.authtime);
740         var u = grabUser(auth_result.payload.authtoken, true);
741         if(u && ! suppressEvents) 
742                 runEvt( "common", "locationChanged", u.ws_ou(), findOrgDepth(u.ws_ou()) );
743
744         checkUserSkin();
745
746         return u;
747 }
748
749 function doLogout() {
750
751         /* cancel everything else */
752         abortAllRequests();
753
754         /* be nice and delete the session from the server */
755         if(G.user && G.user.session) { 
756                 var req = new Request(LOGIN_DELETE, G.user.session);
757       req.send(true);
758                 try { req.result(); } catch(E){}
759     }
760
761         G.user = null;
762
763         /* remove any cached data */
764     dojo.require('dojo.cookie');
765     dojo.cookie(COOKIE_SES, '', {expires:-1});
766     dojo.cookie(COOKIE_RIDS, '', {expires:-1});
767     dojo.cookie(COOKIE_SKIN, '', {expires:-1});
768     dojo.cookie(COOKIE_SEARCH, '', {expires:-1});
769
770
771         checkUserSkin("default");
772         COUNT = 10;
773
774
775         var args = {};
776         args[PARAM_TERM] = "";
777         args[PARAM_LOCATION] = getOrigLocation();
778         args[PARAM_DEPTH] = findOrgDepth(getOrigLocation());
779         args.page = "home";
780
781         
782         var nored = false;
783         try{ if(isFrontPage) nored = true; } catch(e){nored = false;}
784         if(!nored) goTo(buildOPACLink(args));
785 }
786
787
788 function hideMe(obj) { addCSSClass(obj, config.css.hide_me); } 
789 function unHideMe(obj) { removeCSSClass(obj, config.css.hide_me); }
790
791
792 /* ----------------------------------------------------------------------- */
793 /* build the org tree */
794 /* ----------------------------------------------------------------------- */
795 function drawOrgTree() {
796         //setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 10 );
797         setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 1 );
798 }
799         
800 var orgTreeSelector;
801 function buildOrgSelector(node) {
802         var tree = new SlimTree(node,'orgTreeSelector');
803         orgTreeSelector = tree;
804         for( var i in orgArraySearcher ) { 
805                 var node = orgArraySearcher[i];
806                 if( node == null ) continue;
807         if(!isXUL() && !isTrue(node.opac_visible())) continue; 
808                 if(node.parent_ou() == null)
809                         tree.addNode(node.id(), -1, node.name(), 
810                                 "javascript:orgSelect(" + node.id() + ");", node.name());
811                 else {
812                         tree.addNode(node.id(), node.parent_ou(), node.name(), 
813                                 "javascript:orgSelect(" + node.id() + ");", node.name());
814                 }
815         }
816         hideMe($('org_loading_div'));
817         unHideMe($('org_selector_tip'));
818         return tree;
819 }
820
821 function orgSelect(id) {
822         showCanvas();
823         runEvt("common", "locationChanged", id, findOrgDepth(id) );
824
825
826         var loc = findOrgLasso(getLasso());
827         if (!loc) loc = findOrgUnit(id);
828
829         removeChildren(G.ui.common.now_searching);
830         G.ui.common.now_searching.appendChild(text(loc.name()));
831 }
832
833 function setFontSize(size) {
834         scaleFonts(size);
835         cookieManager.write(COOKIE_FONT, size, '+1y');
836 }
837
838 var resourceFormats = [
839    "text",
840    "moving image",
841    "sound recording", "software, multimedia",
842    "still image",
843    "cartographic",
844    "mixed material",
845    "notated music",
846    "three dimensional object" ];
847
848
849 function modsFormatToMARC(format) {
850    switch(format) {
851       case "text":
852          return "at";
853       case "moving image":
854          return "g";
855       case "sound recording":
856          return "ij";
857       case "sound recording-nonmusical":
858          return "i";
859       case "sound recording-musical":
860          return "j";
861       case "software, multimedia":
862          return "m";
863       case "still image":
864          return "k";
865       case "cartographic":
866          return "ef";
867       case "mixed material":
868          return "op";
869       case "notated music":
870          return "cd";
871       case "three dimensional object":
872          return "r";
873    }
874    return "at";
875 }
876
877
878 function MARCFormatToMods(format) {
879    switch(format) {
880       case "a":
881       case "t":
882          return "text";
883       case "g":
884          return "moving image";
885       case "i":
886          return "sound recording-nonmusical";
887       case "j":
888          return "sound recording-musical";
889       case "m":
890          return "software, multimedia";
891       case "k":
892          return "still image";
893       case "e":
894       case "f":
895          return "cartographic";
896       case "o":
897       case "p":
898          return "mixed material";
899       case "c":
900       case "d":
901          return "notated music";
902       case "r":
903          return "three dimensional object";
904    }
905    return "text";
906 }
907
908 function MARCTypeToFriendly(format) {
909         var words = $('format_words');
910         switch(format) {
911                 case 'a' :
912                 case 't' : return $n(words, 'at').innerHTML;
913                 default:
914                         var node = $n(words,format);
915                         if( node ) return node.innerHTML;
916         }
917         return "";
918 }
919
920 function setResourcePic( img, resource ) {
921         img.setAttribute( "src", "../../../../images/tor/" + resource + ".jpg");
922         img.title = resource;
923 }
924
925
926
927 function msg( text ) {
928         try { alert( text ); } catch(e) {}
929 }
930
931 function findRecord(id,type) {
932         try {
933                 for( var i = 0; i != recordsCache.length; i++ ) {
934                         var rec = recordsCache[i];
935                         if( rec && rec.doc_id() == id ) return rec;
936                 }
937         } catch(E){}
938         var meth = FETCH_RMODS
939         if(type == 'M') meth = FETCH_MRMODS;
940         var req = new Request(meth, id);
941         req.request.alertEvent = false;
942         req.send(true);
943         var res = req.result();
944         if( checkILSEvent(res) ) return null; 
945         return res;
946 }
947
948 function Timer(name, node){
949         this.name = name;
950         this.count = 1;
951         this.node = node;
952 }
953 Timer.prototype.start = 
954         function(){_timerRun(this.name);}
955 Timer.prototype.stop = 
956         function(){this.done = true;}
957 function _timerRun(tname) {
958         var _t;
959         eval('_t='+tname);
960         if(_t.done) return;
961         if(_t.count > 100) return;
962         var str = ' . ';
963         if( (_t.count % 5) == 0 ) 
964                 str = _t.count / 5;
965         _t.node.appendChild(text(str));
966         setTimeout("_timerRun('"+tname+"');", 200);
967         _t.count++;
968 }
969
970 function checkILSEvent(obj) {
971         if( obj && obj.ilsevent != null && obj.ilsevent != 0 )
972                 return parseInt(obj.ilsevent);
973         return null;
974 }
975
976
977 function alertILSEvent(evt, msg) {
978    if(!msg) msg = "";
979         if(msg)
980                 alert(msg +'\n' + evt.textcode + '\n' + evt.desc );
981         else 
982                 alert(evt.textcode + '\n' + evt.desc );
983 }
984
985
986 var __authTimer;
987 function AuthTimer(time) { 
988         this.time = (time - LOGOUT_WARNING_TIME) * 1000; 
989         if(__authTimer) 
990                 try {clearTimeout(__authTimer.id)} catch(e){}
991         __authTimer = this;
992 }
993
994 AuthTimer.prototype.run = function() {
995         this.id = setTimeout('_authTimerAlert()', this.time);
996 }
997
998 function _authTimerAlert() {
999         alert( $('auth_session_expiring').innerHTML );
1000         if(!grabUser(null, true)) doLogout();
1001 }
1002
1003
1004 function grabUserByBarcode( authtoken, barcode ) {
1005         var req = new Request( FETCH_USER_BYBARCODE, authtoken, barcode );
1006         req.send(true);
1007         return req.result();
1008 }
1009
1010
1011 function goHome() {
1012         goTo(buildOPACLink({page:HOME}));
1013 }
1014
1015
1016 function buildOrgSel(selector, org, offset, namecol) {
1017     if(!namecol) namecol = 'name';
1018     if(!isXUL() && !isTrue(org.opac_visible())) return;
1019         insertSelectorVal( selector, -1, 
1020                 org[namecol](), org.id(), null, findOrgDepth(org) - offset );
1021         for( var c in org.children() )
1022                 buildOrgSel( selector, org.children()[c], offset, namecol);
1023 }
1024
1025 function buildMergedOrgSel(selector, org_list, offset, namecol) {
1026     if(!namecol) namecol = 'name';
1027     for(var i = 0; i < org_list.length; i++) {
1028         var org = findOrgUnit(org_list[i]);
1029         insertSelectorVal( selector, -1, 
1030                     org[namecol](), org.id(), null, findOrgDepth(org) - offset );
1031             for( var c in org.children() )
1032                     buildOrgSel( selector, org.children()[c], offset, namecol);
1033     }
1034 }
1035
1036
1037 function parseForm(form) {
1038         if(!form) return {};
1039
1040         var it = form.replace(/-\w+$/,"");
1041         var itf = null;
1042         var item_form;
1043         var item_type;
1044
1045         if(form.match(/-/)) itf = form.replace(/^\w+-/,"");
1046
1047         if(it) {
1048                 item_type = [];
1049                 for( var i = 0; i < it.length; i++ ) 
1050                         item_type.push( it.charAt(i) );
1051         }
1052
1053         if(itf) {
1054                 item_form = [];
1055                 for( var i = 0; i < itf.length; i++ ) 
1056                         item_form.push( itf.charAt(i) );
1057         }
1058
1059         return {item_type: item_type, item_form:item_form};
1060 }
1061
1062
1063 function isTrue(x) { return ( x && x != "0" && !(x+'').match(/^f$/i) ); }
1064
1065 function fetchPermOrgs() {
1066         var a = []; /* why does arguments come accross as an object and not an array? */
1067         for( var i = 0; i < arguments.length; i++ ) 
1068                 a.push(arguments[i])
1069
1070         var preq = new Request(FETCH_HIGHEST_PERM_ORG, 
1071                 G.user.session, G.user.id(), a );
1072         preq.send(true);
1073         return preq.result();
1074 }
1075
1076
1077 function print_tabs(t) {
1078         var r = '';
1079         for (var j = 0; j < t; j++ ) { r = r + "  "; }
1080         return r;
1081 }
1082 function formatJSON(s) {
1083         var r = ''; var t = 0;
1084         for (var i in s) {
1085                 if (s[i] == '{' || s[i] == '[' ) {
1086                         r = r + s[i] + "\n" + print_tabs(++t);
1087                 } else if (s[i] == '}' || s[i] == ']') {
1088                         t--; r = r + "\n" + print_tabs(t) + s[i];
1089                 } else if (s[i] == ',') {
1090                         r = r + s[i] + "\n" + print_tabs(t);
1091                 } else {
1092                         r = r + s[i];
1093                 }
1094         }
1095         return r;
1096 }