]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/opac_utils.js
added truth test and using for holdability check
[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.send(true);
586    var auth_result = auth_request.result();
587         if(!auth_result) return null;
588
589         AUTHTIME = parseInt(auth_result.payload.authtime);
590         var u = grabUser(auth_result.payload.authtoken, true);
591         if(u && ! suppressEvents) 
592                 runEvt( "common", "locationChanged", u.ws_ou(), findOrgDepth(u.ws_ou()) );
593
594         checkUserSkin();
595
596         return u;
597 }
598
599 function doLogout(noredirect) {
600
601         /* cancel everything else */
602         abortAllRequests();
603
604         /* be nice and delete the session from the server */
605         if(G.user && G.user.session) { 
606                 var req = new Request(LOGIN_DELETE, G.user.session);
607       req.send(true);
608                 try { req.result(); } catch(E){}
609     }
610
611         G.user = null;
612
613         /* remove any cached data */
614         //cookieManager.remove(COOKIE_IDS);
615         //cookieManager.remove(COOKIE_SRIDS);
616         cookieManager.remove(COOKIE_RIDS);
617         cookieManager.remove(COOKIE_SES);
618         cookieManager.remove(COOKIE_SKIN);
619
620         checkUserSkin("default");
621         COUNT = 10;
622
623
624         var args = {};
625         args[PARAM_TERM] = "";
626         args[PARAM_LOCATION] = globalOrgTree.id();
627         args[PARAM_DEPTH] = findOrgDepth(globalOrgTree);
628         args.page = "home";
629
630         
631         var nored = false;
632         try{ if(isFrontPage) nored = true; } catch(e){nored = false;}
633         if(!nored) goTo(buildOPACLink(args));
634 }
635
636
637 function hideMe(obj) { addCSSClass(obj, config.css.hide_me); } 
638 function unHideMe(obj) { removeCSSClass(obj, config.css.hide_me); }
639
640
641 /* ----------------------------------------------------------------------- */
642 /* build the org tree */
643 /* ----------------------------------------------------------------------- */
644 function drawOrgTree() {
645         //setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 10 );
646         setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 1 );
647 }
648         
649 var orgTreeSelector;
650 function buildOrgSelector(node) {
651         var tree = new SlimTree(node,'orgTreeSelector');
652         orgTreeSelector = tree;
653         for( var i in orgArraySearcher ) { 
654                 var node = orgArraySearcher[i];
655                 if( node == null ) continue;
656                 if(node.parent_ou() == null)
657                         tree.addNode(node.id(), -1, node.name(), 
658                                 "javascript:orgSelect(" + node.id() + ");", node.name());
659                 else {
660                         tree.addNode(node.id(), findOrgUnit(node.parent_ou()).id(), node.name(), 
661                                 "javascript:orgSelect(" + node.id() + ");", node.name());
662                 }
663         }
664         hideMe($('org_loading_div'));
665         unHideMe($('org_selector_tip'));
666         return tree;
667 }
668
669 function orgSelect(id) {
670         showCanvas();
671         runEvt("common", "locationChanged", id, findOrgDepth(id) );
672
673         removeChildren(G.ui.common.now_searching);
674         G.ui.common.now_searching.appendChild(text(findOrgUnit(id).name()));
675 }
676
677 function setFontSize(size) {
678         scaleFonts(size);
679         cookieManager.write(COOKIE_FONT, size, '+1y');
680 }
681
682
683 var resourceFormats = [
684    "text",
685    "moving image",
686    "sound recording", "software, multimedia",
687    "still images",
688    "cartographic",
689    "mixed material",
690    "notated music",
691    "three dimensional object" ];
692
693
694 function modsFormatToMARC(format) {
695    switch(format) {
696       case "text":
697          return "at";
698       case "moving image":
699          return "g";
700       case "sound recording":
701          return "ij";
702       case "sound recording-nonmusical":
703          return "i";
704       case "sound recording-musical":
705          return "j";
706       case "software, multimedia":
707          return "m";
708       case "still images":
709          return "k";
710       case "cartographic":
711          return "ef";
712       case "mixed material":
713          return "op";
714       case "notated music":
715          return "cd";
716       case "three dimensional object":
717          return "r";
718    }
719    return "at";
720 }
721
722
723 function MARCFormatToMods(format) {
724    switch(format) {
725       case "a":
726       case "t":
727          return "text";
728       case "g":
729          return "moving image";
730       case "i":
731          return "sound recording-nonmusical";
732       case "j":
733          return "sound recording-musical";
734       case "m":
735          return "software, multimedia";
736       case "k":
737          return "still images";
738       case "e":
739       case "f":
740          return "cartographic";
741       case "o":
742       case "p":
743          return "mixed material";
744       case "c":
745       case "d":
746          return "notated music";
747       case "r":
748          return "three dimensional object";
749    }
750    return "text";
751 }
752
753 function MARCTypeToFriendly(format) {
754         var words = $('format_words');
755         switch(format) {
756                 case 'a' :
757                 case 't' : return $n(words, 'at').innerHTML;
758                 default:
759                         var node = $n(words,format);
760                         if( node ) return node.innerHTML;
761         }
762         return "";
763 }
764
765 function setResourcePic( img, resource ) {
766         img.setAttribute( "src", "../../../../images/tor/" + resource + ".jpg");
767         img.title = resource;
768 }
769
770
771
772 function msg( text ) {
773         try { alert( text ); } catch(e) {}
774 }
775
776 function findRecord(id,type) {
777         try {
778                 for( var i = 0; i != recordsCache.length; i++ ) {
779                         var rec = recordsCache[i];
780                         if( rec && rec.doc_id() == id ) return rec;
781                 }
782         } catch(E){}
783         var meth = FETCH_RMODS
784         if(type == 'M') meth = FETCH_MRMODS;
785         var req = new Request(meth, id);
786         req.send(true);
787         return req.result();
788 }
789
790 function Timer(name, node){
791         this.name = name;
792         this.count = 1;
793         this.node = node;
794 }
795 Timer.prototype.start = 
796         function(){_timerRun(this.name);}
797 Timer.prototype.stop = 
798         function(){this.done = true;}
799 function _timerRun(tname) {
800         var _t;
801         eval('_t='+tname);
802         if(_t.done) return;
803         if(_t.count > 100) return;
804         var str = ' . ';
805         if( (_t.count % 5) == 0 ) 
806                 str = _t.count / 5;
807         _t.node.appendChild(text(str));
808         setTimeout("_timerRun('"+tname+"');", 200);
809         _t.count++;
810 }
811
812 function checkILSEvent(obj) {
813         if( obj && obj.ilsevent != null && obj.ilsevent != 0 )
814                 return parseInt(obj.ilsevent);
815         return null;
816 }
817
818 /*
819 function alertILSEvent(code, msg) {
820    if(!msg) msg = "";
821         alert( msg + '\n' + $('ilsevent.' + code).innerHTML );
822 }
823 */
824
825 function alertILSEvent(evt, msg) {
826    if(!msg) msg = "";
827         alert(evt.textcode + '\n' + evt.desc );
828 }
829
830
831 var __authTimer;
832 function AuthTimer(time) { 
833         this.time = (time - LOGOUT_WARNING_TIME) * 1000; 
834         __authTimer = this;
835 }
836
837 AuthTimer.prototype.run = function() {
838         setTimeout('_authTimerAlert()', this.time);
839 }
840
841 function _authTimerAlert() {
842         alert( $('auth_session_expiring').innerHTML );
843         if(!grabUser(null, true)) doLogout();
844 }
845
846
847 function grabUserByBarcode( authtoken, barcode ) {
848         var req = new Request( FETCH_USER_BYBARCODE, authtoken, barcode );
849         req.send(true);
850         return req.result();
851 }
852
853
854 function goHome() {
855         goTo(buildOPACLink({page:HOME}));
856 }
857
858
859 function buildOrgSel(selector, org, offset) {
860         insertSelectorVal( selector, -1, 
861                 org.name(), org.id(), null, findOrgDepth(org) - offset );
862         for( var c in org.children() )
863                 buildOrgSel( selector, org.children()[c], offset);
864 }
865
866
867 function parseForm(form) {
868         if(!form) return {};
869
870         var it = form.replace(/-\w+$/,"");
871         var itf = null;
872         var item_form;
873         var item_type;
874
875         if(form.match(/-/)) itf = form.replace(/^\w+-/,"");
876
877         if(it) {
878                 item_type = [];
879                 for( var i = 0; i < it.length; i++ ) 
880                         item_type.push( it.charAt(i) );
881         }
882
883         if(itf) {
884                 item_form = [];
885                 for( var i = 0; i < itf.length; i++ ) 
886                         item_form.push( itf.charAt(i) );
887         }
888
889         return {item_type: item_type, item_form:item_form};
890 }
891
892
893 function isTrue(x) { return ( x && x != "0" && x != 'f' ); }