]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/opac_utils.js
Display an array of MFHD records per bib record
[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         link.setAttribute("href", buildOPACLink(args));
477 }
478
479 function buildTitleDetailLink(rec, link) {
480         if(!rec) return;
481         link.appendChild(text(normalize(truncate(rec.title(), 65))));
482         var args = {};
483         args.page = RDETAIL;
484         //args[PARAM_OFFSET] = 0;
485         args[PARAM_RID] = rec.doc_id();
486         link.setAttribute("href", buildOPACLink(args));
487 }
488
489 /* 'type' is one of STYPE_AUTHOR, STYPE_SUBJECT, ... found in config.js 
490         'trunc' is the number of characters to show in the string, defaults to 65 */
491 function buildSearchLink(type, string, linknode, trunc) {
492         if(!trunc) trunc = 65;
493         var args = {};
494         if( SHOW_MR_DEFAULT) {
495                 args.page = MRESULT;
496         } else {
497                 args.page = RRESULT;
498                 args[PARAM_RTYPE] = type;
499         }
500         args[PARAM_OFFSET] = 0;
501         args[PARAM_TERM] = string;
502         args[PARAM_STYPE] = type;
503         linknode.appendChild(text(normalize(truncate(string, trunc))));
504         linknode.setAttribute("href", buildOPACLink(args));
505 }
506
507 function setSessionCookie(ses) {
508         cookieManager.write(COOKIE_SES, ses, -1);
509 }
510
511
512
513 /* ----------------------------------------------------------------------- */
514 /* user session handling */
515 /* ----------------------------------------------------------------------- */
516 /* session is the login session.  If no session is provided, we attempt
517         to find one in the cookies.  If 'force' is true we retrieve the 
518         user from the server even if there is already a global user present.
519         if ses != G.user.session, we also force a grab */
520 function grabUser(ses, force) {
521
522         if(!ses && isXUL()) {
523                 stash = fetchXULStash();
524                 ses = stash.session.key
525                 _debug("stash auth token = " + ses);
526         }
527
528         if(!ses) {
529                 ses = cookieManager.read(COOKIE_SES);
530                 /* https cookies don't show up in http servers.. */
531         }
532
533         if(!ses) return false;
534
535         if(!force) 
536                 if(G.user && G.user.session == ses)
537                         return G.user;
538
539         /* first make sure the session is valid */
540         var request = new Request(FETCH_SESSION, ses, 1 );
541         request.request.alertEvent = false;
542         request.send(true);
543         var user = request.result();
544
545         if(!user) {
546                 doLogout();
547                 return false; /* unable to grab the session */
548         }
549
550         if( !(typeof user == 'object' && user._isfieldmapper) ) {
551                 doLogout();
552                 return false;
553         }
554
555         G.user = user;
556         G.user.fleshed = false;
557         G.user.session = ses;
558         setSessionCookie(ses);
559
560         grabUserPrefs();
561         if(G.user.prefs['opac.hits_per_page'])
562                 COUNT = parseInt(G.user.prefs['opac.hits_per_page']);
563
564         if(G.user.prefs[PREF_DEF_FONT]) 
565                 setFontSize(G.user.prefs[PREF_DEF_FONT]);
566
567         var at = getAuthtime();
568         //if(isXUL()) at = xulG['authtime'];
569
570         if(at && !isXUL()) new AuthTimer(at).run(); 
571         return G.user;
572 }
573
574
575 /* sets the 'prefs' field of the user object to their preferences 
576         and returns the preferences */
577 function grabUserPrefs(user, force) {
578         if(user == null) user = G.user;
579         if(!force && user.prefs) return user.prefs;     
580         var req = new Request(FETCH_USER_PREFS, user.session, user.id());
581         req.send(true);
582         user.prefs = req.result();
583         return user.prefs;
584 }
585
586 function grabFleshedUser() {
587
588         if(!G.user || !G.user.session) {
589                 grabUser();     
590                 if(!G.user || !G.user.session) return null;
591         }
592
593         if(G.user.fleshed) return G.user;
594
595    var req = new Request(FETCH_FLESHED_USER, G.user.session);
596         req.send(true);
597
598         G.user = req.result();
599
600         if(!G.user || G.user.length == 0) { 
601                 G.user = null; return false; 
602                 cookieManager.write(COOKIE_SES,"");
603         }
604
605         G.user.session = ses;
606         G.user.fleshed = true;
607
608         setSessionCookie(ses);
609         return G.user;
610 }
611
612 function checkUserSkin(new_skin) {
613
614         return; /* XXX do some debugging with this... */
615
616         var user_skin = getSkin();
617         var cur_skin = grabSkinFromURL();
618
619         if(new_skin) user_skin = new_skin;
620
621         if(!user_skin) {
622
623                 if(grabUser()) {
624                         if(grabUserPrefs()) {
625                                 user_skin = G.user.prefs["opac.skin"];
626                                 cookieManager.write( COOKIE_SKIN, user_skin, '+1y' );
627                         }
628                 }
629         }
630
631         if(!user_skin) return;
632
633         if( cur_skin != user_skin ) {
634                 var url = buildOPACLink();
635                 goTo(url.replace(cur_skin, user_skin));
636         }
637 }
638
639 function updateUserSetting(setting, value, user) {
640         if(user == null) user = G.user;
641         var a = {};
642         a[setting] = value;
643         var req = new Request( UPDATE_USER_PREFS, user.session, a );
644         req.send(true);
645         return req.result();
646 }
647
648 function commitUserPrefs() {
649         var req = new Request( 
650                 UPDATE_USER_PREFS, G.user.session, null, G.user.prefs );
651         req.send(true);
652         return req.result();
653 }
654
655 function grabSkinFromURL() {
656         var path = findBasePath();
657         path = path.replace("/xml/", "");
658         var skin = "";
659         for( var i = path.length - 1; i >= 0; i-- ) {
660                 var ch = path.charAt(i);
661                 if(ch == "/") break;
662                 skin += ch;
663         }
664
665         var skin2 = "";
666         for( i = skin.length - 1; i >= 0; i--)
667                 skin2 += skin.charAt(i);
668
669         return skin2;
670 }
671
672
673 /* returns a fleshed G.user on success, false on failure */
674 function doLogin(suppressEvents) {
675
676         abortAllRequests();
677
678         var uname = G.ui.login.username.value;
679         var passwd = G.ui.login.password.value; 
680
681         var init_request = new Request( LOGIN_INIT, uname );
682    init_request.send(true);
683    var seed = init_request.result();
684
685    if( ! seed || seed == '0') {
686       alert( "Error Communicating with Authentication Server" );
687       return null;
688    }
689
690         var args = {
691                 password : hex_md5(seed + hex_md5(passwd)), 
692                 type            : "opac", 
693                 org             : getOrigLocation()
694         };
695
696     r = fetchOrgSettingDefault(globalOrgTree.id(), 'opac.barcode_regex');
697     if(r) REGEX_BARCODE = new RegExp(r);
698     
699     if( uname.match(REGEX_BARCODE) ) args.barcode = uname;
700         else args.username = uname;
701
702    var auth_request = new Request( LOGIN_COMPLETE, args );
703
704         auth_request.request.alertEvent = false;
705    auth_request.send(true);
706    var auth_result = auth_request.result();
707
708         if(!auth_result) {
709                 alertId('patron_login_failed');
710                 return null;
711         }
712
713         if( checkILSEvent(auth_result) ) {
714
715                 if( auth_result.textcode == 'PATRON_INACTIVE' ) {
716                         alertId('patron_inactive_alert');
717                         return;
718                 }
719
720                 if( auth_result.textcode == 'PATRON_CARD_INACTIVE' ) {
721                         alertId('patron_card_inactive_alert');
722                         return;
723                 }
724
725                 if( auth_result.textcode == 'LOGIN_FAILED' || 
726                                 auth_result.textcode == 'PERM_FAILURE' ) {
727                         alertId('patron_login_failed');
728                         return;
729                 }
730         }
731
732
733         AUTHTIME = parseInt(auth_result.payload.authtime);
734         var u = grabUser(auth_result.payload.authtoken, true);
735         if(u && ! suppressEvents) 
736                 runEvt( "common", "locationChanged", u.ws_ou(), findOrgDepth(u.ws_ou()) );
737
738         checkUserSkin();
739
740         return u;
741 }
742
743 function doLogout() {
744
745         /* cancel everything else */
746         abortAllRequests();
747
748         /* be nice and delete the session from the server */
749         if(G.user && G.user.session) { 
750                 var req = new Request(LOGIN_DELETE, G.user.session);
751       req.send(true);
752                 try { req.result(); } catch(E){}
753     }
754
755         G.user = null;
756
757         /* remove any cached data */
758     dojo.require('dojo.cookie');
759     dojo.cookie(COOKIE_SES, '', {expires:-1});
760     dojo.cookie(COOKIE_RIDS, '', {expires:-1});
761     dojo.cookie(COOKIE_SKIN, '', {expires:-1});
762     dojo.cookie(COOKIE_SEARCH, '', {expires:-1});
763
764
765         checkUserSkin("default");
766         COUNT = 10;
767
768
769         var args = {};
770         args[PARAM_TERM] = "";
771         args[PARAM_LOCATION] = getOrigLocation();
772         args[PARAM_DEPTH] = findOrgDepth(getOrigLocation());
773         args.page = "home";
774
775         
776         var nored = false;
777         try{ if(isFrontPage) nored = true; } catch(e){nored = false;}
778         if(!nored) goTo(buildOPACLink(args));
779 }
780
781
782 function hideMe(obj) { addCSSClass(obj, config.css.hide_me); } 
783 function unHideMe(obj) { removeCSSClass(obj, config.css.hide_me); }
784
785
786 /* ----------------------------------------------------------------------- */
787 /* build the org tree */
788 /* ----------------------------------------------------------------------- */
789 function drawOrgTree() {
790         //setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 10 );
791         setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 1 );
792 }
793         
794 var orgTreeSelector;
795 function buildOrgSelector(node) {
796         var tree = new SlimTree(node,'orgTreeSelector');
797         orgTreeSelector = tree;
798         for( var i in orgArraySearcher ) { 
799                 var node = orgArraySearcher[i];
800                 if( node == null ) continue;
801         if(!isXUL() && !isTrue(node.opac_visible())) continue; 
802                 if(node.parent_ou() == null)
803                         tree.addNode(node.id(), -1, node.name(), 
804                                 "javascript:orgSelect(" + node.id() + ");", node.name());
805                 else {
806                         tree.addNode(node.id(), node.parent_ou(), node.name(), 
807                                 "javascript:orgSelect(" + node.id() + ");", node.name());
808                 }
809         }
810         hideMe($('org_loading_div'));
811         unHideMe($('org_selector_tip'));
812         return tree;
813 }
814
815 function orgSelect(id) {
816         showCanvas();
817         runEvt("common", "locationChanged", id, findOrgDepth(id) );
818
819
820         var loc = findOrgLasso(getLasso());
821         if (!loc) loc = findOrgUnit(id);
822
823         removeChildren(G.ui.common.now_searching);
824         G.ui.common.now_searching.appendChild(text(loc.name()));
825 }
826
827 function setFontSize(size) {
828         scaleFonts(size);
829         cookieManager.write(COOKIE_FONT, size, '+1y');
830 }
831
832 var resourceFormats = [
833    "text",
834    "moving image",
835    "sound recording", "software, multimedia",
836    "still image",
837    "cartographic",
838    "mixed material",
839    "notated music",
840    "three dimensional object" ];
841
842
843 function modsFormatToMARC(format) {
844    switch(format) {
845       case "text":
846          return "at";
847       case "moving image":
848          return "g";
849       case "sound recording":
850          return "ij";
851       case "sound recording-nonmusical":
852          return "i";
853       case "sound recording-musical":
854          return "j";
855       case "software, multimedia":
856          return "m";
857       case "still image":
858          return "k";
859       case "cartographic":
860          return "ef";
861       case "mixed material":
862          return "op";
863       case "notated music":
864          return "cd";
865       case "three dimensional object":
866          return "r";
867    }
868    return "at";
869 }
870
871
872 function MARCFormatToMods(format) {
873    switch(format) {
874       case "a":
875       case "t":
876          return "text";
877       case "g":
878          return "moving image";
879       case "i":
880          return "sound recording-nonmusical";
881       case "j":
882          return "sound recording-musical";
883       case "m":
884          return "software, multimedia";
885       case "k":
886          return "still image";
887       case "e":
888       case "f":
889          return "cartographic";
890       case "o":
891       case "p":
892          return "mixed material";
893       case "c":
894       case "d":
895          return "notated music";
896       case "r":
897          return "three dimensional object";
898    }
899    return "text";
900 }
901
902 function MARCTypeToFriendly(format) {
903         var words = $('format_words');
904         switch(format) {
905                 case 'a' :
906                 case 't' : return $n(words, 'at').innerHTML;
907                 default:
908                         var node = $n(words,format);
909                         if( node ) return node.innerHTML;
910         }
911         return "";
912 }
913
914 function setResourcePic( img, resource ) {
915         img.setAttribute( "src", "../../../../images/tor/" + resource + ".jpg");
916         img.title = resource;
917 }
918
919
920
921 function msg( text ) {
922         try { alert( text ); } catch(e) {}
923 }
924
925 function findRecord(id,type) {
926         try {
927                 for( var i = 0; i != recordsCache.length; i++ ) {
928                         var rec = recordsCache[i];
929                         if( rec && rec.doc_id() == id ) return rec;
930                 }
931         } catch(E){}
932         var meth = FETCH_RMODS
933         if(type == 'M') meth = FETCH_MRMODS;
934         var req = new Request(meth, id);
935         req.request.alertEvent = false;
936         req.send(true);
937         var res = req.result();
938         if( checkILSEvent(res) ) return null; 
939         return res;
940 }
941
942 function Timer(name, node){
943         this.name = name;
944         this.count = 1;
945         this.node = node;
946 }
947 Timer.prototype.start = 
948         function(){_timerRun(this.name);}
949 Timer.prototype.stop = 
950         function(){this.done = true;}
951 function _timerRun(tname) {
952         var _t;
953         eval('_t='+tname);
954         if(_t.done) return;
955         if(_t.count > 100) return;
956         var str = ' . ';
957         if( (_t.count % 5) == 0 ) 
958                 str = _t.count / 5;
959         _t.node.appendChild(text(str));
960         setTimeout("_timerRun('"+tname+"');", 200);
961         _t.count++;
962 }
963
964 function checkILSEvent(obj) {
965         if( obj && obj.ilsevent != null && obj.ilsevent != 0 )
966                 return parseInt(obj.ilsevent);
967         return null;
968 }
969
970
971 function alertILSEvent(evt, msg) {
972    if(!msg) msg = "";
973         if(msg)
974                 alert(msg +'\n' + evt.textcode + '\n' + evt.desc );
975         else 
976                 alert(evt.textcode + '\n' + evt.desc );
977 }
978
979
980 var __authTimer;
981 function AuthTimer(time) { 
982         this.time = (time - LOGOUT_WARNING_TIME) * 1000; 
983         if(__authTimer) 
984                 try {clearTimeout(__authTimer.id)} catch(e){}
985         __authTimer = this;
986 }
987
988 AuthTimer.prototype.run = function() {
989         this.id = setTimeout('_authTimerAlert()', this.time);
990 }
991
992 function _authTimerAlert() {
993         alert( $('auth_session_expiring').innerHTML );
994         if(!grabUser(null, true)) doLogout();
995 }
996
997
998 function grabUserByBarcode( authtoken, barcode ) {
999         var req = new Request( FETCH_USER_BYBARCODE, authtoken, barcode );
1000         req.send(true);
1001         return req.result();
1002 }
1003
1004
1005 function goHome() {
1006         goTo(buildOPACLink({page:HOME}));
1007 }
1008
1009
1010 function buildOrgSel(selector, org, offset, namecol) {
1011     if(!namecol) namecol = 'name';
1012     if(!isXUL() && !isTrue(org.opac_visible())) return;
1013         insertSelectorVal( selector, -1, 
1014                 org[namecol](), org.id(), null, findOrgDepth(org) - offset );
1015         for( var c in org.children() )
1016                 buildOrgSel( selector, org.children()[c], offset, namecol);
1017 }
1018
1019 function buildMergedOrgSel(selector, org_list, offset, namecol) {
1020     if(!namecol) namecol = 'name';
1021     for(var i = 0; i < org_list.length; i++) {
1022         var org = findOrgUnit(org_list[i]);
1023         insertSelectorVal( selector, -1, 
1024                     org[namecol](), org.id(), null, findOrgDepth(org) - offset );
1025             for( var c in org.children() )
1026                     buildOrgSel( selector, org.children()[c], offset, namecol);
1027     }
1028 }
1029
1030
1031 function parseForm(form) {
1032         if(!form) return {};
1033
1034         var it = form.replace(/-\w+$/,"");
1035         var itf = null;
1036         var item_form;
1037         var item_type;
1038
1039         if(form.match(/-/)) itf = form.replace(/^\w+-/,"");
1040
1041         if(it) {
1042                 item_type = [];
1043                 for( var i = 0; i < it.length; i++ ) 
1044                         item_type.push( it.charAt(i) );
1045         }
1046
1047         if(itf) {
1048                 item_form = [];
1049                 for( var i = 0; i < itf.length; i++ ) 
1050                         item_form.push( itf.charAt(i) );
1051         }
1052
1053         return {item_type: item_type, item_form:item_form};
1054 }
1055
1056
1057 function isTrue(x) { return ( x && x != "0" && !(x+'').match(/^f$/i) ); }
1058
1059 function fetchPermOrgs() {
1060         var a = []; /* why does arguments come accross as an object and not an array? */
1061         for( var i = 0; i < arguments.length; i++ ) 
1062                 a.push(arguments[i])
1063
1064         var preq = new Request(FETCH_HIGHEST_PERM_ORG, 
1065                 G.user.session, G.user.id(), a );
1066         preq.send(true);
1067         return preq.result();
1068 }
1069
1070
1071 function print_tabs(t) {
1072         var r = '';
1073         for (var j = 0; j < t; j++ ) { r = r + "  "; }
1074         return r;
1075 }
1076 function formatJSON(s) {
1077         var r = ''; var t = 0;
1078         for (var i in s) {
1079                 if (s[i] == '{' || s[i] == '[' ) {
1080                         r = r + s[i] + "\n" + print_tabs(++t);
1081                 } else if (s[i] == '}' || s[i] == ']') {
1082                         t--; r = r + "\n" + print_tabs(t) + s[i];
1083                 } else if (s[i] == ',') {
1084                         r = r + s[i] + "\n" + print_tabs(t);
1085                 } else {
1086                         r = r + s[i];
1087                 }
1088         }
1089         return r;
1090 }