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