]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/opac_utils.js
b699f46fc1cbc3536c65eb62a4b6a44905d1ab79
[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 uname = G.ui.login.username.value;
716         var passwd = G.ui.login.password.value; 
717
718         var init_request = new Request( LOGIN_INIT, uname );
719    init_request.send(true);
720    var seed = init_request.result();
721
722    if( ! seed || seed == '0') {
723       alert( "Error Communicating with Authentication Server" );
724       return null;
725    }
726
727         var args = {
728                 password : hex_md5(seed + hex_md5(passwd)), 
729                 type            : "opac", 
730                 org             : getOrigLocation()
731         };
732
733     r = fetchOrgSettingDefault(globalOrgTree.id(), 'opac.barcode_regex');
734     if(r) REGEX_BARCODE = new RegExp(r);
735     
736     if( uname.match(REGEX_BARCODE) ) args.barcode = uname;
737         else args.username = uname;
738
739    var auth_request = new Request( LOGIN_COMPLETE, args );
740
741         auth_request.request.alertEvent = false;
742    auth_request.send(true);
743    var auth_result = auth_request.result();
744
745         if(!auth_result) {
746                 alertId('patron_login_failed');
747                 return null;
748         }
749
750         if( checkILSEvent(auth_result) ) {
751
752                 if( auth_result.textcode == 'PATRON_INACTIVE' ) {
753                         alertId('patron_inactive_alert');
754                         return;
755                 }
756
757                 if( auth_result.textcode == 'PATRON_CARD_INACTIVE' ) {
758                         alertId('patron_card_inactive_alert');
759                         return;
760                 }
761
762                 if( auth_result.textcode == 'LOGIN_FAILED' || 
763                                 auth_result.textcode == 'PERM_FAILURE' ) {
764                         alertId('patron_login_failed');
765                         return;
766                 }
767         }
768
769
770         AUTHTIME = parseInt(auth_result.payload.authtime);
771         var u = grabUser(auth_result.payload.authtoken, true);
772         if(u && ! suppressEvents) 
773                 runEvt( "common", "locationChanged", u.ws_ou(), findOrgDepth(u.ws_ou()) );
774
775         checkUserSkin();
776
777         return u;
778 }
779
780 function doLogout() {
781
782         /* cancel everything else */
783         abortAllRequests();
784
785         /* be nice and delete the session from the server */
786         if(G.user && G.user.session) { 
787                 var req = new Request(LOGIN_DELETE, G.user.session);
788       req.send(true);
789                 try { req.result(); } catch(E){}
790     }
791
792         G.user = null;
793
794         /* remove any cached data */
795     dojo.require('dojo.cookie');
796     dojo.cookie(COOKIE_SES, null, {expires:-1});
797     dojo.cookie(COOKIE_RIDS, null, {expires:-1});
798     dojo.cookie(COOKIE_SKIN, null, {expires:-1});
799     dojo.cookie(COOKIE_SEARCH, null, {expires:-1});
800
801
802         checkUserSkin("default");
803         COUNT = 10;
804
805
806         var args = {};
807         args[PARAM_TERM] = "";
808         args[PARAM_LOCATION] = getOrigLocation();
809     args[PARAM_DEPTH] = findOrgDepth(getOrigLocation() || globalOrgTree);
810         args.page = "home";
811
812         
813         var nored = false;
814         try{ if(isFrontPage) nored = true; } catch(e){nored = false;}
815         if(!nored) goTo(buildOPACLink(args, false, false));
816 }
817
818
819 function hideMe(obj) { addCSSClass(obj, config.css.hide_me); } 
820 function unHideMe(obj) { removeCSSClass(obj, config.css.hide_me); }
821
822
823 /* ----------------------------------------------------------------------- */
824 /* build the org tree */
825 /* ----------------------------------------------------------------------- */
826 function drawOrgTree() {
827         //setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 10 );
828         setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 1 );
829 }
830
831 var checkOrgHiding_cached = false;
832 var checkOrgHiding_cached_context_org;
833 var checkOrgHiding_cached_depth;
834 function checkOrgHiding() {
835     if (isXUL()) {
836         return false; // disable org hiding for staff client
837     }
838     var context_org = getOrigLocation() || globalOrgTree.id();
839     var depth;
840     if (checkOrgHiding_cached) {
841         if (checkOrgHiding_cached_context_org != context_org) {
842             checkOrgHiding_cached_context_org = context_org;
843             checkOrgHiding_cached_depth = undefined;
844             checkOrgHiding_cached = false;
845         } else {
846             depth = checkOrgHiding_cached_depth;
847         }
848     } else {
849         depth = fetchOrgSettingDefault( context_org, 'opac.org_unit_hiding.depth');
850         checkOrgHiding_cached_depth = depth;
851         checkOrgHiding_cached_context_org = context_org;
852         checkOrgHiding_cached = true;
853     }
854     if ( findOrgDepth( context_org ) < depth ) {
855         return false; // disable org hiding if Original Location doesn't make sense with setting depth (avoids disjointed org selectors)
856     }
857     if (depth) {
858         return { 'org' : findOrgUnit(context_org), 'depth' : depth };
859     } else {
860         return false;
861     }
862 }
863
864 var orgTreeSelector;
865 function buildOrgSelector(node) {
866         var tree = new SlimTree(node,'orgTreeSelector');
867         orgTreeSelector = tree;
868         var orgHiding = checkOrgHiding();
869         for( var i in orgArraySearcher ) { 
870                 var node = orgArraySearcher[i];
871                 if( node == null ) continue;
872                 if(!isXUL() && !isTrue(node.opac_visible())) continue; 
873                 if (orgHiding) {
874                         if ( ! orgIsMine( orgHiding.org, node, orgHiding.depth ) ) {
875                                 continue;
876                         }
877                 }
878                 if(node.parent_ou() == null) {
879                         tree.addNode(node.id(), -1, node.name(), 
880                                 "javascript:orgSelect(" + node.id() + ");", node.name());
881                 } else {
882                         if (orgHiding && orgHiding.depth == findOrgDepth(node)) {
883                                 tree.addNode(node.id(), -1, node.name(), 
884                                         "javascript:orgSelect(" + node.id() + ");", node.name());
885                         } else {
886                                 tree.addNode(node.id(), node.parent_ou(), node.name(), 
887                                         "javascript:orgSelect(" + node.id() + ");", node.name());
888                         }
889                 }
890         }
891         hideMe($('org_loading_div'));
892         unHideMe($('org_selector_tip'));
893         return tree;
894 }
895
896 function orgSelect(id) {
897         showCanvas();
898         runEvt("common", "locationChanged", id, findOrgDepth(id) );
899
900
901         var loc = findOrgLasso(getLasso());
902         if (!loc) loc = findOrgUnit(id);
903
904         removeChildren(G.ui.common.now_searching);
905         G.ui.common.now_searching.appendChild(text(loc.name()));
906 }
907
908 function setFontSize(size) {
909         scaleFonts(size);
910         dojo.cookie(COOKIE_FONT, size, { 'expires' : 365});
911 }
912
913 var resourceFormats = [
914    "text",
915    "moving image",
916    "sound recording", "software, multimedia",
917    "still image",
918    "cartographic",
919    "mixed material",
920    "notated music",
921    "three dimensional object" ];
922
923
924 function modsFormatToMARC(format) {
925    switch(format) {
926       case "text":
927          return "at";
928       case "moving image":
929          return "g";
930       case "sound recording":
931          return "ij";
932       case "sound recording-nonmusical":
933          return "i";
934       case "sound recording-musical":
935          return "j";
936       case "software, multimedia":
937          return "m";
938       case "still image":
939          return "k";
940       case "cartographic":
941          return "ef";
942       case "mixed material":
943          return "op";
944       case "notated music":
945          return "cd";
946       case "three dimensional object":
947          return "r";
948    }
949    return "at";
950 }
951
952
953 function MARCFormatToMods(format) {
954    switch(format) {
955       case "a":
956       case "t":
957          return "text";
958       case "g":
959          return "moving image";
960       case "i":
961          return "sound recording-nonmusical";
962       case "j":
963          return "sound recording-musical";
964       case "m":
965          return "software, multimedia";
966       case "k":
967          return "still image";
968       case "e":
969       case "f":
970          return "cartographic";
971       case "o":
972       case "p":
973          return "mixed material";
974       case "c":
975       case "d":
976          return "notated music";
977       case "r":
978          return "three dimensional object";
979    }
980    return "text";
981 }
982
983 function MARCTypeToFriendly(format) {
984         var words = $('format_words');
985         switch(format) {
986                 case 'a' :
987                 case 't' : return $n(words, 'at').innerHTML;
988                 default:
989                         var node = $n(words,format);
990                         if( node ) return node.innerHTML;
991         }
992         return "";
993 }
994
995 function setResourcePic( img, resource ) {
996         img.setAttribute( "src", "../../../../images/tor/" + resource + ".jpg");
997         img.title = resource;
998 }
999
1000
1001
1002 function msg( text ) {
1003         try { alert( text ); } catch(e) {}
1004 }
1005
1006 function findRecord(id,type) {
1007         try {
1008                 for( var i = 0; i != recordsCache.length; i++ ) {
1009                         var rec = recordsCache[i];
1010                         if( rec && rec.doc_id() == id ) return rec;
1011                 }
1012         } catch(E){}
1013         var meth = FETCH_RMODS
1014         if(type == 'M') meth = FETCH_MRMODS;
1015         var req = new Request(meth, id);
1016         req.request.alertEvent = false;
1017         req.send(true);
1018         var res = req.result();
1019         if( checkILSEvent(res) ) return null; 
1020         return res;
1021 }
1022
1023 function Timer(name, node){
1024         this.name = name;
1025         this.count = 1;
1026         this.node = node;
1027 }
1028 Timer.prototype.start = 
1029         function(){_timerRun(this.name);}
1030 Timer.prototype.stop = 
1031         function(){this.done = true;}
1032 function _timerRun(tname) {
1033         var _t;
1034         eval('_t='+tname);
1035         if(_t.done) return;
1036         if(_t.count > 100) return;
1037         var str = ' . ';
1038         if( (_t.count % 5) == 0 ) 
1039                 str = _t.count / 5;
1040         _t.node.appendChild(text(str));
1041         setTimeout("_timerRun('"+tname+"');", 200);
1042         _t.count++;
1043 }
1044
1045 function checkILSEvent(obj) {
1046         if (obj && typeof obj == 'object' && typeof obj.ilsevent != 'undefined') {
1047         if (obj.ilsevent === '') {
1048             return true;
1049         } else if ( obj.ilsevent != null && obj.ilsevent != 0 ) {
1050             return parseInt(obj.ilsevent);
1051         }
1052     }
1053         return null;
1054 }
1055
1056
1057 function alertILSEvent(evt, msg) {
1058    if(!msg) msg = "";
1059         if(msg)
1060                 alert(msg +'\n' + evt.textcode + '\n' + evt.desc );
1061         else 
1062                 alert(evt.textcode + '\n' + evt.desc );
1063 }
1064
1065
1066 var __authTimer;
1067 function AuthTimer(time) { 
1068         this.time = (time - LOGOUT_WARNING_TIME) * 1000; 
1069         if(__authTimer) 
1070                 try {clearTimeout(__authTimer.id)} catch(e){}
1071         __authTimer = this;
1072 }
1073
1074 AuthTimer.prototype.run = function() {
1075         this.id = setTimeout('_authTimerAlert()', this.time);
1076 }
1077
1078 function _authTimerAlert() {
1079         alert( $('auth_session_expiring').innerHTML );
1080         if(!grabUser(null, true)) doLogout();
1081 }
1082
1083
1084 function grabUserByBarcode( authtoken, barcode ) {
1085         var req = new Request( FETCH_USER_BYBARCODE, authtoken, barcode );
1086         req.send(true);
1087         return req.result();
1088 }
1089
1090
1091 function goHome() {
1092         goTo(buildOPACLink({page:HOME}));
1093 }
1094
1095
1096 function buildOrgSel(selector, org, offset, namecol) {
1097     if(!namecol) namecol = 'name';
1098     if(!isXUL() && !isTrue(org.opac_visible())) return;
1099         insertSelectorVal( selector, -1, 
1100                 org[namecol](), org.id(), null, findOrgDepth(org) - offset );
1101     var kids = org.children();
1102     if (kids) {
1103             for( var c = 0; c < kids.length; c++ )
1104                     buildOrgSel( selector, kids[c], offset, namecol);
1105     }
1106 }
1107
1108 function buildMergedOrgSel(selector, org_list, offset, namecol) {
1109     if(!namecol) namecol = 'name';
1110     for(var i = 0; i < org_list.length; i++) {
1111         var org = findOrgUnit(org_list[i]);
1112         insertSelectorVal( selector, -1, 
1113                     org[namecol](), org.id(), null, findOrgDepth(org) - offset );
1114         var kids = org.children();
1115         if (kids) {
1116                 for( var c = 0; c < kids.length; c++ )
1117                         buildOrgSel( selector, kids[c], offset, namecol);
1118         }
1119     }
1120 }
1121
1122
1123 function parseForm(form) {
1124         if(!form) return {};
1125
1126         var it = form.replace(/-\w+$/,"");
1127         var itf = null;
1128         var item_form;
1129         var item_type;
1130
1131         if(form.match(/-/)) itf = form.replace(/^\w+-/,"");
1132
1133         if(it) {
1134                 item_type = [];
1135                 for( var i = 0; i < it.length; i++ ) 
1136                         item_type.push( it.charAt(i) );
1137         }
1138
1139         if(itf) {
1140                 item_form = [];
1141                 for( var i = 0; i < itf.length; i++ ) 
1142                         item_form.push( itf.charAt(i) );
1143         }
1144
1145         return {item_type: item_type, item_form:item_form};
1146 }
1147
1148
1149 function isTrue(x) { return ( x && x != "0" && !(x+'').match(/^f$/i) ); }
1150
1151 function fetchPermOrgs() {
1152         var a = []; /* Q: why does arguments come accross as an object and not an array? A: because arguments is a special object, a collection */
1153
1154         for( var i = 0; i < arguments.length; i++ ) 
1155                 a.push(arguments[i])
1156
1157         var preq = new Request(FETCH_HIGHEST_PERM_ORG, 
1158                 G.user.session, G.user.id(), a );
1159         preq.send(true);
1160         return preq.result();
1161 }
1162
1163
1164 function print_tabs(t) {
1165         var r = '';
1166         for (var j = 0; j < t; j++ ) { r = r + "  "; }
1167         return r;
1168 }
1169 function formatJSON(s) {
1170         var r = ''; var t = 0;
1171         for (var i in s) {
1172                 if (s[i] == '{' || s[i] == '[' ) {
1173                         r = r + s[i] + "\n" + print_tabs(++t);
1174                 } else if (s[i] == '}' || s[i] == ']') {
1175                         t--; r = r + "\n" + print_tabs(t) + s[i];
1176                 } else if (s[i] == ',') {
1177                         r = r + s[i] + "\n" + print_tabs(t);
1178                 } else {
1179                         r = r + s[i];
1180                 }
1181         }
1182         return r;
1183 }