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