adding
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Fri, 19 Aug 2005 19:27:32 +0000 (19:27 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Fri, 19 Aug 2005 19:27:32 +0000 (19:27 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@1681 dcc99617-32d9-48b4-a31d-7c20da2025e4

50 files changed:
Open-ILS/web/opac/common/css/dtree.css [new file with mode: 0644]
Open-ILS/web/opac/common/css/largefont.css [new file with mode: 0644]
Open-ILS/web/opac/common/css/mediumfont.css [new file with mode: 0644]
Open-ILS/web/opac/common/css/smallfont.css [new file with mode: 0644]
Open-ILS/web/opac/common/js/CGI.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/Cookie.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/JSON.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/OrgTree.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/RemoteRequest.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/config.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/dtree.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/fmcore.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/fmgen.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/init.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/md5.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/opac_utils.js [new file with mode: 0644]
Open-ILS/web/opac/common/js/utils.js [new file with mode: 0644]
Open-ILS/web/opac/images/main_logo.jpg [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/base.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/cd.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/empty.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/folder.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/folderopen.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/globe.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/imgfolder.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/join.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/joinbottom.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/line.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/minus.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/minusbottom.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/musicfolder.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/nolines_minus.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/nolines_plus.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/page.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/plus.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/plusbottom.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/question.gif [new file with mode: 0644]
Open-ILS/web/opac/images/orgtree/trash.gif [new file with mode: 0644]
Open-ILS/web/opac/images/small_logo.jpg [new file with mode: 0644]
Open-ILS/web/opac/images/tor/cartographic.jpg [new file with mode: 0644]
Open-ILS/web/opac/images/tor/mixed material.jpg [new file with mode: 0644]
Open-ILS/web/opac/images/tor/moving image.jpg [new file with mode: 0644]
Open-ILS/web/opac/images/tor/notated music.jpg [new file with mode: 0644]
Open-ILS/web/opac/images/tor/software, multimedia.jpg [new file with mode: 0644]
Open-ILS/web/opac/images/tor/sound recording-musical.jpg [new file with mode: 0644]
Open-ILS/web/opac/images/tor/sound recording-nonmusical.jpg [new file with mode: 0644]
Open-ILS/web/opac/images/tor/sound recording.jpg [new file with mode: 0644]
Open-ILS/web/opac/images/tor/still images.jpg [new file with mode: 0644]
Open-ILS/web/opac/images/tor/three dimensional object.jpg [new file with mode: 0644]
Open-ILS/web/opac/locale/en-US/lang.dtd [new file with mode: 0644]

diff --git a/Open-ILS/web/opac/common/css/dtree.css b/Open-ILS/web/opac/common/css/dtree.css
new file mode 100644 (file)
index 0000000..b201c2f
--- /dev/null
@@ -0,0 +1,34 @@
+/*--------------------------------------------------|
+| dTree 2.05 | www.destroydrop.com/javascript/tree/ |
+|---------------------------------------------------|
+| Copyright (c) 2002-2003 Geir Landrö               |
+|--------------------------------------------------*/
+
+.dtree {
+       font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
+       font-size: 11px;
+       color: #666;
+       white-space: nowrap;
+}
+.dtree img {
+       border: 0px;
+       vertical-align: middle;
+}
+.dtree a {
+       color: #333;
+       text-decoration: none;
+}
+.dtree a.node, .dtree a.nodeSel {
+       white-space: nowrap;
+       padding: 1px 2px 1px 2px;
+}
+.dtree a.node:hover, .dtree a.nodeSel:hover {
+       color: #333;
+       text-decoration: underline;
+}
+.dtree a.nodeSel {
+       background-color: #c0d2ec;
+}
+.dtree .clip {
+       overflow: hidden;
+}
\ No newline at end of file
diff --git a/Open-ILS/web/opac/common/css/largefont.css b/Open-ILS/web/opac/common/css/largefont.css
new file mode 100644 (file)
index 0000000..18c86dd
--- /dev/null
@@ -0,0 +1,13 @@
+body                           { font-family: Helvetica, Arial, Tahoma, sans-serif; font-size: 1.5em; } 
+body table             { font-size: inherit; }
+
+.org_link { font-size: 92%; }
+.sidebar_extra_item { font-size: 95%; }
+.searchbar_tag { font-size: 90%; } 
+#offset_start { font-weight: 600; }
+#offset_end { font-weight: 600; }
+#result_count { font-weight: 600; } 
+.nav_link_active { font-weight: 600;}
+.copy_count_cell { font-size: 80%; }
+
+
diff --git a/Open-ILS/web/opac/common/css/mediumfont.css b/Open-ILS/web/opac/common/css/mediumfont.css
new file mode 100644 (file)
index 0000000..5762738
--- /dev/null
@@ -0,0 +1,13 @@
+body                           { font-family: Helvetica, Arial, Tahoma, sans-serif; font-size: 75%;} 
+body table             { font-size: inherit; }
+
+.org_link { font-size: 92%; }
+.sidebar_extra_item { font-size: 95%; }
+.searchbar_tag { font-size: 90%; } 
+#offset_start { font-weight: 600; }
+#offset_end { font-weight: 600; }
+#result_count { font-weight: 600; } 
+.nav_link_active { font-weight: 600;}
+.copy_count_cell { font-size: 80%; }
+
+
diff --git a/Open-ILS/web/opac/common/css/smallfont.css b/Open-ILS/web/opac/common/css/smallfont.css
new file mode 100644 (file)
index 0000000..594aac1
--- /dev/null
@@ -0,0 +1,13 @@
+body                           { font-family: Helvetica, Arial, Tahoma, sans-serif; font-size: 50%; } 
+body table             { font-size: inherit; }
+
+.org_link { font-size: 92%; }
+.sidebar_extra_item { font-size: 95%; }
+.searchbar_tag { font-size: 90%; } 
+#offset_start { font-weight: 600; }
+#offset_end { font-weight: 600; }
+#result_count { font-weight: 600; } 
+.nav_link_active { font-weight: 600;}
+.copy_count_cell { font-size: 80%; }
+
+
diff --git a/Open-ILS/web/opac/common/js/CGI.js b/Open-ILS/web/opac/common/js/CGI.js
new file mode 100644 (file)
index 0000000..7d11096
--- /dev/null
@@ -0,0 +1,74 @@
+function CGI() {
+       /* load up the url parameters */
+
+       this._keys = new Array();
+       this.data = new Object();
+
+       var string = location.search.replace(/^\?/,"");
+
+       var key = ""; 
+       var value = "";
+       var inkey = true;
+       var invalue = false;
+
+       for( var idx = 0; idx!= string.length; idx++ ) {
+
+               var c = string.charAt(idx);
+
+               if( c == "=" )  {
+                       invalue = true;
+                       inkey = false;
+                       continue;
+               } 
+
+               if(c == "&" || c == ";") {
+                       inkey = 1;
+                       invalue = 0;
+                       this.data[key] = decodeURIComponent(value);
+                       this._keys.push(key);
+                       key = ""; value = "";
+                       continue;
+               }
+
+               if(inkey) key += c;
+               else if(invalue) value += c;
+       }
+
+       this.data[key] = decodeURIComponent(value);
+       this._keys.push(key);
+}
+
+/* returns the value for the given param.  If there is only one value for the
+   given param, it returns that value.  Otherwise it returns an array of values
+ */
+CGI.prototype.param = function(p) {
+       if(this.data[p] == null) return null;
+
+       if(this.data[p].length == 1)
+               return this.data[p][0];
+       return this.data[p];
+}
+
+/* returns an array of param names */
+CGI.prototype.keys = function() {
+       return this._keys;
+}
+
+/* debuggin method */
+CGI.prototype.toString = function() {
+       var string = "";
+       var keys = this.keys();
+
+       for( var k in keys ) {
+               string += keys[k] + " : ";
+               var params = this.param(keys[k]);
+
+               for( var p in params ) {
+                       string +=  params[p] + " ";
+               }
+               string += "\n";
+       }
+       return string;
+}
+
+
diff --git a/Open-ILS/web/opac/common/js/Cookie.js b/Open-ILS/web/opac/common/js/Cookie.js
new file mode 100644 (file)
index 0000000..8d4e6e3
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+
+DISCLAIMER: THESE JAVASCRIPT FUNCTIONS ARE SUPPLIED 'AS IS', WITH 
+NO WARRANTY EXPRESSED OR IMPLIED. YOU USE THEM AT YOUR OWN RISK. 
+PAUL STEPHENS DOES NOT ACCEPT ANY LIABILITY FOR 
+ANY LOSS OR DAMAGE RESULTING FROM THEIR USE, HOWEVER CAUSED. 
+
+Paul Stephens' cookie-handling object library
+
+Version 2.1
+2.0 - Introduces field names
+2.1 - Fixes bug where undefined embedded fields[] elements weren't written to disk
+
+www.paulspages.co.uk 
+
+TO USE THIS LIBRARY, INSERT ITS CONTENTS IN THE <HEAD> SECTION 
+OF YOUR WEB PAGE SOURCE, BEFORE ANY OTHER JAVASCRIPT ROUTINES.
+
+(C) Paul Stephens, 2001-2003. Feel free to use this code, but please leave this comment block in. This code must not be sold, either alone or as part of an application, without the consent of the author.
+*/
+
+function cookieObject(name, expires, accessPath) {
+var i, j
+this.name = name
+this.fieldSeparator = "#"
+this.found = false
+this.expires = expires
+this.accessPath = accessPath
+this.rawValue = ""
+this.fields = new Array()
+this.fieldnames = new Array() 
+if (arguments.length > 3) { // field name(s) specified
+  j = 0
+  for (i = 3; i < arguments.length; i++) {
+    this.fieldnames[j] = arguments[i]    
+    j++
+  }
+  this.fields.length = this.fieldnames.length 
+}
+this.read = ucRead
+
+this.write = ucWrite
+
+this.remove = ucDelete
+this.get = ucFieldGet
+this.put = ucFieldPut
+this.namepos = ucNamePos
+this.read()
+}
+
+
+function ucFieldGet(fieldname) {
+var i = this.namepos(fieldname)
+if (i >=0) {
+  return this.fields[i]
+} else {
+  return "BadFieldName!"
+}
+}
+
+function ucFieldPut (fieldname, fieldval) {
+var i = this.namepos(fieldname)
+
+if(i < 0) {
+       i = this.fieldnames.length;
+       this.fieldnames[i] = fieldname;
+}
+
+this.fields[i] = fieldval
+return true
+}
+
+function ucNamePos(fieldname) {
+var i 
+for (i = 0; i < this.fieldnames.length; i++) {
+  if (fieldname == this.fieldnames[i]) {
+    return i
+  }
+}
+return -1
+}
+
+
+function ucWrite() {      
+  var cookietext = this.name + "=" 
+
+// concatenate array elements into cookie string
+// Special case - single-field cookie, so write without # terminator
+if (this.fields.length == 1) {
+  cookietext += escape(this.fields[0])
+  } else { // multi-field cookie
+    for (i= 0; i < this.fields.length; i++) {
+      cookietext += escape(this.fields[i]) + this.fieldSeparator }
+  }
+
+
+// Set expiry parameter, if specified
+    if (this.expires != null) {  
+      if (typeof(this.expires) == "number") { // Expiry period in days specified  
+        var today=new Date()     
+        var expiredate = new Date()      
+        expiredate.setTime(today.getTime() + 1000*60*60*24*this.expires)
+        cookietext += "; expires=" + expiredate.toGMTString()
+      } else { // assume it's a date object
+        cookietext +=  "; expires=" + this.expires.toGMTString()
+      } // end of typeof(this.expires) if
+    } // end of this.expires != null if 
+   
+// add path, if specified
+   if (this.accessPath != null) {
+   cookietext += "; PATH="+this.accessPath }
+
+// write cookie
+   // alert("writing "+cookietext)
+   document.cookie = cookietext 
+   return null  
+}
+
+
+function ucRead() {
+  var search = this.name + "="                       
+  var CookieString = document.cookie            
+  if(CookieString == null) CookieString = "";
+  this.rawValue = null
+  this.found = false     
+  if (CookieString.length > 0) {                
+    offset = CookieString.indexOf(search)       
+    if (offset != -1) {                         
+      offset += search.length                   
+      end = CookieString.indexOf(";", offset)   
+      if (end == -1) {  // cookie is last item in the string, so no terminator                        
+       end = CookieString.length }              
+      this.rawValue = CookieString.substring(offset, end)                                   
+      this.found = true 
+      } 
+    }
+   
+if (this.rawValue != null) { // unpack into fields
+
+  var sl = this.rawValue.length
+  var startidx = 0
+  var endidx = 0
+  var i = 0
+
+// Special case - single-field cookies written by other functions,
+// so without a '#' terminator
+
+if (this.rawValue.substr(sl-1, 1) != this.fieldSeparator) {
+  this.fields[0] = unescape(this.rawValue)
+  } else { // separate fields
+
+  do  
+  {
+   endidx = this.rawValue.indexOf(this.fieldSeparator, startidx)
+   if (endidx !=-1) {
+     this.fields[i] = unescape(this.rawValue.substring(startidx, endidx))
+     i++
+     startidx = endidx + 1}
+  }
+  while (endidx !=-1 & endidx != (this.rawValue.length -1));
+}
+} // end of unpack into fields if block
+  return this.found
+} // end of function
+
+
+function ucDelete() {
+  this.expires = -10
+  this.write()
+  return this.read()
+}
+
+
diff --git a/Open-ILS/web/opac/common/js/JSON.js b/Open-ILS/web/opac/common/js/JSON.js
new file mode 100644 (file)
index 0000000..e52a439
--- /dev/null
@@ -0,0 +1,135 @@
+// in case we run on an implimentation that doesn't have "undefined";
+var undefined;
+
+function Cast (obj, class_constructor) {
+       try {
+               if (eval(class_constructor + '["_isfieldmapper"]')) {
+                       obj = eval("new " + class_constructor + "(obj)");
+               }
+       } catch( E ) {
+               alert( E + "\n");
+       } finally {
+               return obj;
+       }
+}
+
+function JSON2js (json) {
+
+       json = String(json).replace( /\/\*--\s*S\w*?\s*?\s+\w+\s*--\*\//g, 'Cast(');
+       json = String(json).replace( /\/\*--\s*E\w*?\s*?\s+(\w+)\s*--\*\//g, ', "$1")');
+
+       var obj;
+       if (json != '') {
+               try {
+                       eval( 'obj = ' + json );
+               } catch(E) {
+                       debug("Error building JSON object with string " + E + "\nString:\n" + json );
+                       return null;
+               }
+       }
+       return obj;
+}
+
+
+function object2Array(obj) {
+       if( obj == null ) return null;
+
+       var arr = new Array();
+       for( var i  = 0; i < obj.length; i++ ) {
+               arr[i] = obj[i];
+       }
+       return arr;
+}
+
+
+function js2JSON(arg) {
+       return _js2JSON(arg);
+}
+
+function _js2JSON(arg) {
+       var i, o, u, v;
+
+               switch (typeof arg) {
+                       case 'object':
+       
+                               if(arg) {
+       
+                                       if (arg._isfieldmapper) { /* magi-c-ast for fieldmapper objects */
+       
+                                               if( arg.a.constructor != Array ) {
+                                                       var arr = new Array();
+                                                       for( var i  = 0; i < arg.a.length; i++ ) {
+                                                               if( arg.a[i] == null ) {
+                                                                       arr[i] = null; continue;
+                                                               }
+       
+                                                               if( typeof arg.a[i] != 'object' ) { 
+                                                                       arr[i] = arg.a[i];
+       
+                                                               } else if( typeof arg.a[i] == 'object' 
+                                                                                       && arg.a[i]._isfieldmapper) {
+       
+                                                                       arr[i] = arg.a[i];
+       
+                                                               } else {
+                                                                       arr[i] = object2Array(arg.a[i]);                
+                                                               }
+                                                       }
+                                                       arg.a = arr;
+                                               }
+       
+                                               return "/*--S " + arg.classname + " --*/" + js2JSON(arg.a) + "/*--E " + arg.classname + " --*/";
+       
+                                       } else {
+       
+                                               if (arg.constructor == Array) {
+                                                       o = '';
+                                                       for (i = 0; i < arg.length; ++i) {
+                                                               v = js2JSON(arg[i]);
+                                                               if (o) {
+                                                                       o += ',';
+                                                               }
+                                                               if (v !== u) {
+                                                                       o += v;
+                                                               } else {
+                                                                       o += 'null';
+                                                               }
+                                                       }
+                                                       return '[' + o + ']';
+       
+                                               } else if (typeof arg.toString != 'undefined') {
+                                                       o = '';
+                                                       for (i in arg) {
+                                                               v = js2JSON(arg[i]);
+                                                               if (v !== u) {
+                                                                       if (o) {
+                                                                               o += ',';
+                                                                       }
+                                                                       o += js2JSON(i) + ':' + v;
+                                                               }
+                                                       }
+       
+                                                       o = '{' + o + '}';
+                                                       return o;
+       
+                                               } else {
+                                                       return;
+                                               }
+                                       }
+                               }
+                               return 'null';
+       
+                       case 'unknown':
+                       case 'number':
+                               return arg;
+       
+                       case 'undefined':
+                       case 'function':
+                               return u;
+       
+                       case 'string':
+                       default:
+                               return '"' + String(arg).replace(/(["\\])/g, '\\$1') + '"';
+               }
+
+}
diff --git a/Open-ILS/web/opac/common/js/OrgTree.js b/Open-ILS/web/opac/common/js/OrgTree.js
new file mode 100644 (file)
index 0000000..0a51e00
--- /dev/null
@@ -0,0 +1,37 @@
+var _l = [[1,1,,"Pines"],[146,3,143,"Alexander Public Library"],[64,3,62,"Alma-Bacon County Public Library"],[135,3,134,"Ambrose Public Library"],[278,3,277,"Appleby Branch Library"],[63,3,62,"Appling County Public Library"],[262,3,261,"Arlington Branch Library"],[9,2,1,"Athens Regional Library"],[10,3,9,"Athens-Clarke County Library"],[189,3,188,"Auburn Public Library"],[279,3,277,"Audio/Visual Center/TBC Library"],[288,3,277,"Augusta-Richmond County Public Library"],[255,3,254,"Baker County Library"],[193,3,188,"Banks County Public Library"],[114,3,113,"Barnesville-Lamar County Library"],[218,2,1,"Bartram Trail Regional Library"],[3,3,2,"Berlin Community Library"],[4,3,2,"Berlin Community Library"],[174,3,166,"Betty C. Hagler Public Library"],[66,3,62,"Blackshear Memorial Library"],[161,3,160,"Blackshear Place Library"],[12,3,9,"Bogart Branch Library"],[136,3,134,"Bookmbile--see Douglas-Coffee Co. Library"],[205,3,204,"Bookmbile--see Vidalia-Toombs County Library"],[219,3,218,"Bookmobile"],[272,3,269,"Bookmobile"],[280,3,277,"Bookmobile"],[167,3,166,"Bookmobile"],[65,3,62,"Bookmobile"],[71,3,70,"Bookmobile"],[11,3,9,"Bookmobile"],[24,3,23,"Bookmobile"],[149,3,148,"Bookmobile--See Clarkesville-Habersham Co."],[229,3,228,"Bookmobile--See Louisville Public Library"],[243,3,235,"Bookmobile--See Washington Memorial Library"],[181,3,180,"Bookmobile--see Gilbert H. Gragg Mem. Lib."],[5,3,2,"Bookmobile-See Moultrie-Colquitt County Lib."],[101,3,100,"Bookmobile-See Mountain Regional Lib. Sys."],[85,3,84,"Bookmoible-see Screvens County Library"],[25,3,23,"Bowman Library"],[72,3,70,"Brantley County Library"],[191,3,188,"Braselton Library"],[213,2,1,"Brooks County Library"],[214,3,213,"Brooks County Library"],[137,3,134,"Broxton Public Library"],[169,3,166,"Buchanan - Haralson County Public Library"],[281,3,277,"Burke County Library"],[93,3,92,"Butler Public Library"],[107,3,106,"Byron Public Library"],[263,3,261,"Calhoun County Library"],[73,3,70,"Camden County Public Library"],[271,3,269,"Carrie Dorsey Perry Memorial Library"],[30,3,27,"Cave Spring Branch"],[29,3,27,"Cedartown Branch"],[157,3,156,"Centerville Branch Library"],[36,3,35,"Central Library"],[74,3,70,"Charlton Public Library"],[122,2,1,"Chattooga County Library"],[123,3,122,"Chattooga County Library"],[223,2,1,"Cherokee Regional Library"],[215,2,1,"Chestatee Regional Library"],[224,3,223,"Chickamauga Public Library"],[150,3,148,"Clarkesville-Habersham County Library"],[264,3,261,"Clay County Library"],[127,2,1,"Clayton County Library System"],[129,3,127,"Clayton County Library System"],[162,3,160,"Clermont Branch Library"],[67,3,62,"Clinch County Public Library"],[269,2,1,"Coastal Plain Regional Library"],[275,3,269,"Coastal Plain Regional Library"],[147,3,143,"Cochran Public Library"],[296,3,295,"Cochran-Bleckley/Tessie W. Norris"],[284,3,277,"Columbia County Libraries/Gibbs Memorial"],[192,3,188,"Commerce Public Library"],[125,2,1,"Conyers-Rockdale Library System"],[273,3,269,"Cook County Library"],[152,3,148,"Cornelia-Habersham Library"],[248,3,235,"Crawford County Public Library"],[225,3,223,"Dade County Public Library"],[216,3,215,"Dawson County Library"],[254,2,1,"DeSoto Trail Regional Library"],[35,2,1,"Dougherty County Public Library"],[171,3,166,"Douglas County Public Library"],[138,3,134,"Douglas-Coffee County Library"],[14,3,9,"East Athens Community Center"],[277,2,1,"East Central Georgia Regional Library"],[163,3,160,"East Hall and Special Needs Library"],[236,3,235,"East Wilkinson County Library"],[48,3,41,"Eatonton-Putnam County Library"],[26,3,23,"Elbert County Library"],[23,2,1,"Elbert County Public Library"],[282,3,277,"Euchee Creek Library"],[54,3,53,"Evans County Library"],[94,3,92,"Extension Services"],[102,3,100,"Fannin County Public Library"],[115,3,113,"Fayette County Public Library"],[34,3,33,"Fitzerald-Ben Hill County Library"],[33,2,1,"Fitzgerald-Ben Hill Library"],[113,2,1,"Flint River Regional Library"],[128,3,127,"Forest Park Branch Library"],[144,3,143,"Fortson Public Library"],[59,3,53,"Franklin Memorial Library"],[283,3,277,"Friedman Branch Library"],[237,3,235,"Genealogical and Historical  Department"],[182,3,180,"Gilbert H. Gragg Memorial Library"],[285,3,277,"Glascock County Library"],[210,3,204,"Glennville Public Library"],[238,3,235,"Gordon Public Library"],[42,3,41,"Greene County Library"],[95,3,92,"Greenville Area Public Library"],[117,3,113,"Griffin-Spalding County Library"],[164,3,160,"Hall County Library"],[160,2,1,"Hall County Library System"],[43,3,41,"Hancock County Library"],[286,3,277,"Harlem Branch Library"],[196,3,188,"Harold S. Swindle Public Library"],[186,2,1,"Hart County Library"],[187,3,186,"Hart County Library"],[139,3,134,"Hazlehurst-Jeff Davis Public Library"],[257,3,254,"Hdqtrs Library/Camilla"],[172,3,166,"Heard County Public Library"],[143,2,1,"Henry County Library"],[96,3,92,"Hightower Memorial Library"],[156,2,1,"Houston County Public Library"],[77,3,70,"Ida Hilton Public Library"],[239,3,235,"Ideal Public Library"],[274,3,269,"Irwin County Library"],[121,3,113,"J. Joel Edwards Public Library"],[118,3,113,"Jackson-Butts County Public Library"],[258,3,254,"Jakin Public Library"],[183,3,180,"James W. Merritt Memorial Library"],[44,3,41,"Jasper County Library"],[228,2,1,"Jefferson County Library"],[194,3,188,"Jefferson Public Library"],[86,3,84,"Jenkins County Elementary School"],[87,3,84,"Jenkins County High School"],[88,3,84,"Jenkins County Memorial Library"],[203,3,199,"Johnson County Library"],[240,3,235,"Jones County Public Library"],[130,3,127,"Jonesboro Branch Library"],[261,2,1,"Kinchafoonee Regional Library"],[265,3,261,"Kinchafoonee Regional Library"],[55,3,53,"L.C. Anderson Library"],[226,3,223,"LaFayette-Walker County Library"],[206,3,204,"Ladson Genealogical Library"],[207,3,204,"Ladson Genealogical Library"],[51,3,50,"Lake Sinclair Library"],[16,3,9,"Lavonia-Carnegie Library"],[17,3,9,"Lay Park Community Resource Ctr."],[110,2,1,"Lee County Public Library"],[111,3,110,"Lee County Public Library"],[241,3,235,"Library for the Blind & Physically Handicapped"],[287,3,277,"Lincoln County Library"],[145,3,143,"Locust Grove Public Library"],[76,3,70,"Long County Library"],[230,3,228,"Louisville Public Library"],[131,3,127,"Lovejoy Branch Library (projected)"],[256,3,254,"Lucy Maddox Memorial Library"],[217,3,215,"Lumpkin County Library"],[19,3,9,"Lyndon House Arts Ctr"],[299,3,295,"M.E. Roden Public Library"],[13,3,9,"Madison County Library"],[97,3,92,"Manchester Public Library"],[260,3,254,"Margaret Jones Public Library"],[68,3,62,"Marian Anderson Public Library"],[242,3,235,"Marshallville Public Library"],[52,3,50,"Mary Vinson Memorial Library"],[221,3,218,"Mary Willis Library"],[175,3,166,"Maude P. Ragsdale Public Library"],[290,3,277,"Maxwell Branch Library"],[195,3,188,"Maysville Public Library"],[232,3,228,"McCollum Public Library"],[235,2,1,"Middle Georgia Regional Library"],[289,3,277,"Midville Branch Library"],[184,3,180,"Miller County Public Library"],[116,3,113,"Monroe County Library"],[6,3,2,"Monroe Memorial Library"],[7,3,2,"Monroe Memorial Library"],[46,3,41,"Monroe-Walton County Library"],[244,3,235,"Montezuma Carnegie Public Library"],[209,3,204,"Montgomery County Library"],[45,3,41,"Morgan County Library"],[132,3,127,"Morrow Branch Library"],[2,2,1,"Moultrie-Colquitt County Library"],[8,3,2,"Moultrie-Colquitt County Library"],[100,2,1,"Mountain Regional Library"],[103,3,100,"Mountain Regional Library System"],[165,3,160,"Murrayville Branch Library"],[298,3,295,"Murrell Memorial Library"],[126,3,125,"Nancy Guinn Memorial Library"],[208,3,204,"Nelle Brown Memorial Library"],[173,3,166,"Neva Lomason Memorial Library"],[176,3,166,"New Georgia Public Library"],[234,3,233,"Newton County Library Headqtrs."],[233,2,1,"Newton County Library System"],[140,3,134,"Nicholls Public Library"],[159,3,156,"Nola Brantley Memorial Library"],[148,2,1,"Northeast Georgia Regional Library"],[37,3,35,"Northwest Library"],[47,3,41,"O'Kelly Memorial Library"],[295,2,1,"Ocmulgee Regional Library"],[21,3,9,"Oconee County Library"],[199,2,1,"Oconee Regional Library"],[200,3,199,"Oconee Regional Library"],[80,2,1,"Office of Public Library Services"],[18,3,9,"Oglethorpe County Library"],[245,3,235,"Oglethorpe Public Library"],[204,2,1,"Ohoopee Regional Library"],[62,2,1,"Okefenokee Regional Library System"],[28,3,27,"Outreach Collection"],[177,3,166,"Paulding County Public Library"],[108,3,106,"Peach County Law Enforcement Center"],[106,2,1,"Peach Public Libraries"],[119,3,113,"Peachtree City Library"],[141,3,134,"Pearson Public Library"],[259,3,254,"Pelham-Carnegie Library"],[56,3,53,"Pembroke Public Library"],[158,3,156,"Perry Public Library"],[188,2,1,"Piedmont Regional Library System"],[198,3,188,"Piedmont Regional Library-Headquarters"],[190,3,188,"Piedmont-Bookmobile"],[92,2,1,"Pine Mountain Regional Library"],[60,2,1,"Pine Mountain Regional Library System"],[297,3,295,"Public Service Annex"],[154,3,148,"Rabun County Library"],[266,3,261,"Randolph County Public LIbrary"],[247,3,235,"Regional Library"],[98,3,92,"Reynolds Community Library"],[57,3,53,"Richmond Hill Public Library"],[133,3,127,"Riverdale Branch Library"],[249,3,235,"Riverside Branch Library"],[31,3,27,"Rockmart Branch"],[246,3,235,"Rocky Creek Branch Library"],[90,2,1,"Roddenbery Memorial Library"],[91,3,90,"Roddenbery Memorial Library"],[32,3,27,"Rome-Floyd County Library"],[201,3,199,"Rosa M. Tarbutton Memorial Library/Washington Co."],[227,3,223,"Rossville Public Library"],[20,3,9,"Royston Branch Library"],[15,3,9,"Sandy Creek Nature Ctr"],[27,2,1,"Sara Hightower Regional Library"],[292,3,277,"Sardis Branch Library"],[134,2,1,"Satilla Regional Library"],[89,3,84,"Screven County Library"],[84,2,1,"Screven-Jenkins Regional Library"],[185,3,180,"Seminole Public Library"],[250,3,235,"Shurling Branch Library"],[112,3,110,"Smithville Library"],[291,3,277,"South Augusta Branch Library/ Diamond Lakes Branch Library"],[38,3,35,"Southside Library"],[180,2,1,"Southwest Georgia Regional Library"],[78,3,70,"St. Mary's Library"],[81,3,80,"State Library of Georgia Admin. Offices"],[83,3,80,"State Library of Georgia Collection"],[82,3,80,"State Library of Georgia Library for the Blind"],[53,2,1,"Statesboro Regional Library"],[58,3,53,"Statesboro Regional Library"],[197,3,188,"Statham Public Library"],[99,3,92,"Talbot County Library"],[222,3,218,"Taliaferro County Library"],[178,3,166,"Tallapoosa Public Library"],[39,3,35,"Tallulah Massey Library"],[211,3,204,"Tattnall County Library"],[300,3,295,"Telfair County Library"],[267,3,261,"Terrell County Public Library"],[109,3,106,"Thomas Public Library"],[220,3,218,"Thomson-McDuffie County Library"],[70,2,1,"Three Rivers Regional Library"],[75,3,70,"Three Rivers Regional Library"],[276,3,269,"Tifton-Tift County Public Library"],[155,3,148,"Toccoa-Stephens County Library"],[104,3,100,"Towns County Public Library"],[202,3,199,"Treutlen County Library"],[124,3,122,"Trion Public Library"],[251,3,235,"Twiggs County Public Library"],[50,2,1,"Twin Lakes Library"],[120,3,113,"Tyrone Public Library"],[41,2,1,"Uncle Remus Regional Library"],[105,3,100,"Union County Public Library"],[270,3,269,"Victoria Evans Memorial Library"],[212,3,204,"Vidalia-Toombs County Library"],[179,3,166,"Villa Rica Public Library"],[49,3,41,"W. H. Stanton Memorial Library"],[231,3,228,"Wadley Public Library"],[293,3,277,"Wallace Branch Library"],[294,3,277,"Warren County Library"],[168,3,166,"Warren P. Sewell Memorial Library of Bowdon"],[170,3,166,"Warren P. Sewell Memorial Library of Bremen"],[252,3,235,"Washington Memorial Library"],[69,3,62,"Waycross-Ware County Public Library"],[79,3,70,"Wayne County Library"],[268,3,261,"Webster County Public Library"],[253,3,235,"West Bibb Branch Library"],[166,2,1,"West Georgia Regional Library"],[40,3,35,"Westtown Library"],[301,3,295,"Wheeler County Library"],[302,3,295,"Wheeler County Library"],[151,3,148,"White County Library, Cleveland Branch"],[153,3,148,"White County Library, Helen Branch"],[303,3,295,"Wilcox County Public Library"],[142,3,134,"Willacoochee Public Library"],[22,3,9,"Winterville Branch Library"],[61,3,60,"Yatesville Public Library"]];
+var orgArraySearcher = {};
+var globalOrgTree;
+for (var i in _l) {
+       var x = new aou();
+       x.id(_l[i][0]);
+       x.ou_type(_l[i][1]);
+       x.parent_ou(_l[i][2]);
+       x.name(_l[i][3]);
+       orgArraySearcher[x.id()] = x;
+}
+for (var i in orgArraySearcher) {
+       var x = orgArraySearcher[i];
+       if (x.parent_ou() == null || x.parent_ou() == '') {
+               globalOrgTree = x;
+               continue;
+       } else {
+               x.parent_ou(orgArraySearcher[x.parent_ou()]);
+       }
+       if (!x.parent_ou().children()) 
+               x.parent_ou().children(new Array());
+
+       x.parent_ou().children().push(x.id());
+}
+function _tree_killer () {
+       for (var i in orgArraySearcher) {
+               x=orgArraySearcher[i];
+               x.children(null);
+               x.parent_ou(null);
+               orgArraySearcher[i]=null;
+       }
+       globalOrgTree = null;
+       orgArraySearcher = null;
+       globalOrgTypes = null;
+}
+
+var globalOrgTypes = JSON2js("[/*--S aout--*/[null,null,null,null,0,0,0,1,\"Consortium\",\"Everywhere in PINES\"]/*--E aout--*/,/*--S aout--*/[null,null,null,null,0,0,1,2,\"System\",\"Local Library System\",1]/*--E aout--*/,/*--S aout--*/[null,null,null,null,1,1,2,3,\"Branch\",\"This Branch\",2]/*--E aout--*/,/*--S aout--*/[null,null,null,null,1,1,3,5,\"Bookmobile\",\"Your Bookmobile\",3]/*--E aout--*/,/*--S aout--*/[null,null,null,null,1,1,3,4,\"Sub-lib\",\"This Specialized Library\",3]/*--E aout--*/]");
diff --git a/Open-ILS/web/opac/common/js/RemoteRequest.js b/Open-ILS/web/opac/common/js/RemoteRequest.js
new file mode 100644 (file)
index 0000000..e7fff24
--- /dev/null
@@ -0,0 +1,204 @@
+var XML_HTTP_GATEWAY = "gateway";
+var XML_HTTP_SERVER = "gapines.org";
+var XML_HTTP_MAX_TRIES = 3;
+
+var _allrequests = {};
+
+function cleanRemoteRequests() {
+       for( var i in _allrequests ) 
+               destroyRequest(_allrequests[i]);
+}
+
+function destroyRequest(r) {
+       if(r == null) return;
+       r.xmlhttp.onreadystatechange = function(){};
+       r.xmlhttp                               = null;
+       r.callback                              = null;
+       r.userdata                              = null;
+       _allrequests[r.id]      = null;
+}
+
+/* ----------------------------------------------------------------------- */
+/* Request object */
+function RemoteRequest( service, method ) {
+
+
+       this.service    = service;
+       this.method             = method;
+       this.xmlhttp    = false;
+       this.name               = null;
+       this.sendCount = 0;
+
+       this.type               = "POST"; /* default */
+       this.id                 = service + method + Math.random();
+       this.cancelled = false;
+
+       _allrequests[this.id] = this;
+
+       var i = 2;
+       this.params = ""; 
+
+       while(i < arguments.length) {
+               var object = js2JSON(arguments[i++]);
+               this.params += "&param=" + encodeURIComponent(object);
+       }
+
+       if(!this.params) { this.params = ""; }
+       this.param_string = "service=" + service + "&method=" + method + this.params;
+       if( this.buildXMLRequest() == null ) alert("Browser is not supported!");
+}
+
+/* constructs our XMLHTTPRequest object */
+RemoteRequest.prototype.buildXMLRequest = function() {
+
+       var x;
+       try { 
+               x = new ActiveXObject("Msxml2.XMLHTTP"); 
+       } catch (e) {
+               try { 
+                       x = new ActiveXObject("Microsoft.XMLHTTP"); 
+               } catch (E) {
+                       x = false;
+               }
+       }
+
+       if (!x && typeof XMLHttpRequest!='undefined') x = new XMLHttpRequest();
+
+       if(!x) {
+               alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
+               return null;
+       }
+
+       this.xmlhttp = x;
+       return true;
+}
+
+
+function _remoteRequestCallback(id) {
+
+       var object = _allrequests[id];
+       if(object.cancelled) return;
+
+       if( object.xmlhttp.readyState == 4 ) {
+               try {
+                       object.callback(object);
+               } catch(E) {
+
+                       /* if we receive a communication error, retry the request up
+                               to XML_HTTP_MAX_TRIES attempts */
+                       if( instanceOf(E, EXCommunication) ) {
+
+                               if(object.sendCount >= XML_HTTP_MAX_TRIES ) {
+                                       if(isXUL()) throw object;
+                                        else alert("Arrrgghh, Matey! Error communicating:\n" + E  + "\n" + object.param_string);
+                               } else {
+                                       object.buildXMLRequest();
+                                       object.send();
+                                       return;
+                               }
+                       } else { throw E; }
+
+               } finally { 
+                       destroyRequest(object); 
+                       object = null; 
+               }  
+       }
+}
+
+
+/* define the callback we use when this request has received
+       all of its data */
+RemoteRequest.prototype.setCompleteCallback = function(callback) {
+       if(this.cancelled) return;
+       this.callback = callback;
+       var id = this.id;
+       this.xmlhttp.onreadystatechange = function() { _remoteRequestCallback(id); }
+}
+
+
+/* http by default.  This makes it https. *ONLY works when
+       embedded in a XUL app. */
+RemoteRequest.prototype.setSecure = function(bool) {
+       this.secure = bool; 
+}
+
+RemoteRequest.prototype.send = function(blocking) {
+
+       if(this.cancelled) return;
+
+       /* determine the xmlhttp server dynamically */
+       var url = location.protocol + "//" + location.host + "/" + XML_HTTP_GATEWAY;
+
+       if(isXUL()) {
+               if(this.secure)
+                       url =   "https://" + XML_HTTP_SERVER + "/" + XML_HTTP_GATEWAY;
+               else
+                       url =   "http://" + XML_HTTP_SERVER + "/" + XML_HTTP_GATEWAY;
+       }
+
+       var data = null;
+
+       if( this.type == 'GET' ) { 
+               url +=  "?" + this.param_string; 
+       }
+
+       if(blocking) {
+               this.xmlhttp.open(this.type, url, false);
+       } else {
+               this.xmlhttp.open(this.type, url, true);
+       }
+
+
+       if( this.type == 'POST' ) {
+               data = this.param_string;
+               this.xmlhttp.setRequestHeader('Content-Type',
+                               'application/x-www-form-urlencoded');
+       }
+
+       this.xmlhttp.send( data );
+       this.sendCount += 1;
+       return this;
+}
+
+/* returns the actual response text from the request */
+RemoteRequest.prototype.getText = function() {
+       return this.xmlhttp.responseText;
+}
+
+RemoteRequest.prototype.isReady = function() {
+       return this.xmlhttp.readyState == 4;
+}
+
+
+/* returns the JSON->js result object  */
+RemoteRequest.prototype.getResultObject = function() {
+       if(this.cancelled) return null;
+
+       var text = this.xmlhttp.responseText;
+       var obj = JSON2js(text);
+
+       if(obj == null) return null;
+       if(obj.is_err)  throw new EXCommunication(obj.err_msg); 
+       if( obj[0] != null && obj[1] == null ) obj = obj[0];
+
+       /* these are user level exceptions from the server code */
+       if(instanceOf(obj, ex)) {
+               if(!isXUL()) alert(obj.err_msg());
+               throw obj;
+       }
+
+       if(instanceOf(obj, perm_ex)) {
+               /* the opac will go ahead and spit out the error msg */
+               if(!isXUL()) alert(obj.err_msg());
+               throw obj;
+       }
+
+       return obj;
+}
+
+/* adds a new parameter to the request */
+RemoteRequest.prototype.addParam = function(param) {
+       var string = encodeURIComponent(js2JSON(param));
+       this.param_string += "&param=" + string;
+}
+
diff --git a/Open-ILS/web/opac/common/js/config.js b/Open-ILS/web/opac/common/js/config.js
new file mode 100644 (file)
index 0000000..34593ea
--- /dev/null
@@ -0,0 +1,199 @@
+/* Export some constants  ----------------------------------------------------- */
+
+/* URL params */
+var PARAM_TERM                                 = "term";               /* search term */
+var PARAM_STYPE                                = "stype";              /* search type */
+var PARAM_LOCATION                     = "location"    /* current location */;
+var PARAM_DEPTH                                = "depth";              /* search depth */
+var PARAM_FORM                                 = "format";             /* search format */
+var PARAM_OFFSET                               = "offset";             /* search offset */
+var PARAM_COUNT                                = "count";              /* hits per page */
+var PARAM_HITCOUNT                     = "hitcount";   /* hits per page */
+var PARAM_MRID                                 = "mrid";               /* metarecord id */
+var PARAM_RID                                  = "rid";                        /* record id */
+
+/* cookies */
+var COOKIE_SB = "sbe";
+var COOKIE_SES = "ses";
+var COOKIE_IDS = "ids";
+
+/* these are the actual param values - set on page load */
+
+/* pages */
+var MRESULT            = "mresult";
+var RRESULT            = "rresult";
+var RDETAIL            = "rdetail";
+var MYOPAC             = "myopac";
+var ADVANCED   = "advanced";
+var HOME                       = "home";
+
+/* search type (STYPE) options */
+STYPE_AUTHOR   = "author";
+STYPE_TITLE            = "title";
+STYPE_SUBJECT  = "subject";
+STYPE_SERIES   = "series";
+STYPE_KEYWORD  = "keyword";
+
+
+/* container for global variables shared accross pages */
+var G          = {};
+G.user = null; /* global user object */
+G.ui           = {} /* cache of UI components */
+
+
+/* call me after page init and I will load references 
+       to all of the ui object id's defined below 
+       They will be stored in G.ui.<page>.<thingy>
+ */
+function loadUIObjects() {
+       for( var p in config.ids ) {
+               G.ui[p] = {};
+               for( var o in config.ids[p] ) 
+                       G.ui[p][o] = getId(config.ids[p][o]);
+       }
+}
+
+/* try our best to free memory */
+function clearUIObjects() {
+       for( var p in config.ids ) {
+               for( var o in config.ids[p] ) {
+                       if(G.ui[p][o]) {
+                               G.ui[p][o].onclick = null;
+                               G.ui[p][o].onkeydown = null;
+                               G.ui[p][o] = null;
+                       }
+               }
+               G.ui[p] = null;
+       }
+}
+
+/* ---------------------------------------------------------------------------- 
+       Set up ID's and CSS classes 
+       Any new ids, css, etc. may be added by giving the unique names and putting 
+       them into the correct scope 
+/* ---------------------------------------------------------------------------- */
+
+var config = {};
+
+/* Set up the page names */
+config.page = {};
+config.page[HOME]                      = "index.xml";
+config.page[ADVANCED]  = "advanced.xml";
+config.page[MRESULT]           = "mresult.xml";
+config.page[RRESULT]           = "rresult.xml";
+config.page[MYOPAC]            = "myopac.xml";
+config.page[RDETAIL]           = "rdetail.xml";
+
+
+/* set up images  */
+config.images = {};
+config.images.logo = "main_logo.jpg";
+
+
+/* set up ID's, CSS, and node names */
+config.ids                             = {};
+config.ids.result              = {};
+config.ids.mresult     = {};
+config.ids.advanced    = {};
+config.ids.rresult     = {};
+config.ids.myopac              = {};
+config.ids.rdetail     = {};
+
+config.css                             = {};
+config.css.result              = {};
+config.css.mresult     = {};
+config.css.advanced    = {};
+config.css.rresult     = {};
+config.css.myopac              = {};
+config.css.rdetail     = {};
+
+config.names                   = {};
+config.names.result    = {};
+config.names.mresult = {};
+config.names.advanced = {};
+config.names.rresult = {};
+config.names.myopac    = {};
+config.names.rdetail = {};
+
+
+/* id's shared accross skins. These *must* be defined */
+config.ids.common = {};
+config.ids.common.loading                      = "loading_div";                
+config.ids.common.canvas                       = "canvas";                             
+config.ids.common.canvas_main          = "canvas_main";                
+config.ids.common.org_tree                     = "org_tree";                   
+config.ids.common.org_container        = "org_container";
+
+
+/* shared CSS */
+config.css.hide_me = "hide_me";
+
+
+/* ---------------------------------------------------------------------------- */
+/* These are pages that may replace the canvas */
+/* ---------------------------------------------------------------------------- */
+config.ids.altcanvas = {};
+
+
+
+/* ---------------------------------------------------------------------------- */
+/* Methods are defined as service:method 
+       An optional 3rd component is when a method is followed by a :1, such methods
+       have a staff counterpart and should have ".staff" appended to the method 
+       before the method is called when in XUL mode */
+
+var FETCH_MRCOUNT                              = "open-ils.search:open-ils.search.biblio.class.count:1";
+var FETCH_MRIDS                                = "open-ils.search:open-ils.search.biblio.class:1";
+var FETCH_MRIDS_FULL                   = "open-ils.search:open-ils.search.biblio.class.full:1";
+var FETCH_MRMODS                               = "open-ils.search:open-ils.search.biblio.metarecord.mods_slim.retrieve";
+var FETCH_MR_COPY_COUNTS       = "open-ils.search:open-ils.search.biblio.metarecord.copy_count:1";
+var FETCH_RIDS                                 = "open-ils.search:open-ils.search.biblio.metarecord_to_records:1";
+var FETCH_RMODS                                = "open-ils.search:open-ils.search.biblio.record.mods_slim.retrieve";
+var FETCH_R_COPY_COUNTS                = "open-ils.search:open-ils.search.biblio.record.copy_count";
+var FETCH_FLESHED_USER         = "open-ils.actor:open-ils.actor.user.fleshed.retrieve";
+var FETCH_SESSION                              = "open-ils.auth:open-ils.auth.session.retrieve";
+var LOGIN_INIT                                 = "open-ils.auth:open-ils.auth.authenticate.init";
+var LOGIN_COMPLETE                     = "open-ils.auth:open-ils.auth.authenticate.complete";
+var LOGIN_DELETE                               = "open-ils.auth:open-ils.auth.session.delete";
+/* ---------------------------------------------------------------------------- */
+
+
+
+/* ---------------------------------------------------------------------------- */
+/* event callback functions. Other functions may be appended to these vars to
+       for added functionality.  */
+
+G.evt                          = {}; /* events container */
+
+function runEvt(scope, name, a, b, c, d, e, f, g) {
+       var evt = G.evt[scope][name];
+       for( var i in evt ) evt[i](a, b, c, d, e, f, g);        
+}
+
+/* creates a new event if it doesn't already exist */
+function createEvt(scope, name) {
+       if(!G.evt[scope]) G.evt[scope] = {};
+       if(G.evt[scope][name] == null)
+               G.evt[scope][name] = []; 
+}
+
+function attachEvt(scope, name, action) {
+       createEvt(scope, name);
+       G.evt[scope][name].push(action);
+}
+
+createEvt("common", "init");                                           /* f() : what happens on page init */
+createEvt("common", "unload");                                 /* f() : what happens on window unload (clean memory, etc.)*/
+createEvt("mresult", "run");                                           /* f() : kick of the page*/
+createEvt("mresult", "idsReceived");                   /* f(ids) */
+createEvt("rresult", "run");                                           /* f() : kick of the page*/
+createEvt("rresult", "idsReceived");                   /* f(ids) */    
+
+createEvt("result", "hitCountReceived");               /* f() : display hit info, pagination, etc. */
+createEvt("result", "recordReceived");                 /* f(mvr, pagePosition, isMr) : display the record*/
+createEvt("result", "copyCountsReceived");     /* f(mvr, pagePosition, copyCountInfo) : display copy counts*/
+createEvt("result", "allRecordsReceived");     /* f(mvrsArray) : add other page stuff, sidebars, etc.*/
+
+
+
+
diff --git a/Open-ILS/web/opac/common/js/dtree.js b/Open-ILS/web/opac/common/js/dtree.js
new file mode 100644 (file)
index 0000000..8f95cb0
--- /dev/null
@@ -0,0 +1,324 @@
+/*--------------------------------------------------|
+| dTree 2.05 | www.destroydrop.com/javascript/tree/ |
+|---------------------------------------------------|
+| Copyright (c) 2002-2003 Geir Landrö               |
+|                                                   |
+| This script can be used freely as long as all     |
+| copyright messages are intact.                    |
+|                                                   |
+| Updated: 17.04.2003                               |
+|--------------------------------------------------*/
+
+function Node(id, pid, name, url, title, target, icon, iconOpen, open) {
+       this.id = id;
+       this.pid = pid;
+       this.name = name;
+       this.url = url;
+       this.title = title;
+       this.target = target;
+       this.icon = icon;
+       this.iconOpen = iconOpen;
+       this._io = open || false;
+       this._is = false;
+       this._ls = false;
+       this._hc = false;
+       this._ai = 0;
+       this._p;
+};
+
+function dTree(objName) {
+       this.config = {
+               target                                  : null,
+               folderLinks                     : true,
+               useSelection            : true,
+               useCookies                      : true,
+               useLines                                : true,
+               useIcons                                : true,
+               useStatusText           : false,
+               closeSameLevel  : false,
+               inOrder                                 : false
+       }
+       this.icon = {
+               root                            : '../../../images/orgtree/base.gif',
+               folder                  : '../../../images/orgtree/folder.gif',
+               folderOpen              : '../../../images/orgtree/folderopen.gif',
+               node                            : '../../../images/orgtree/page.gif',
+               empty                           : '../../../images/orgtree/empty.gif',
+               line                            : '../../../images/orgtree/line.gif',
+               join                            : '../../../images/orgtree/join.gif',
+               joinBottom              : '../../../images/orgtree/joinbottom.gif',
+               plus                            : '../../../images/orgtree/plus.gif',
+               plusBottom              : '../../../images/orgtree/plusbottom.gif',
+               minus                           : '../../../images/orgtree/minus.gif',
+               minusBottom             : '../../../images/orgtree/minusbottom.gif',
+               nlPlus                  : '../../../images/orgtree/nolines_plus.gif',
+               nlMinus                 : '../../../images/orgtree/nolines_minus.gif'
+       };
+       this.obj = objName;
+       this.aNodes = [];
+       this.aIndent = [];
+       this.root = new Node(-1);
+       this.selectedNode = null;
+       this.selectedFound = false;
+       this.completed = false;
+};
+
+dTree.prototype.add = function(id, pid, name, url, title, target, icon, iconOpen, open) {
+       this.aNodes[this.aNodes.length] = new Node(id, pid, name, url, title, target, icon, iconOpen, open);
+};
+
+dTree.prototype.openAll = function() {
+       this.oAll(true);
+};
+dTree.prototype.closeAll = function() {
+       this.oAll(false);
+};
+
+dTree.prototype.toString = function() {
+       var str = '<div class="dtree">\n';
+       if (document.getElementById) {
+               if (this.config.useCookies) this.selectedNode = this.getSelected();
+               str += this.addNode(this.root);
+       } else str += 'Browser not supported.';
+       str += '</div>';
+       if (!this.selectedFound) this.selectedNode = null;
+       this.completed = true;
+       return str;
+};
+
+dTree.prototype.addNode = function(pNode) {
+       var str = '';
+       var n=0;
+       if (this.config.inOrder) n = pNode._ai;
+       for (n; n<this.aNodes.length; n++) {
+               if (this.aNodes[n].pid == pNode.id) {
+                       var cn = this.aNodes[n];
+                       cn._p = pNode;
+                       cn._ai = n;
+                       this.setCS(cn);
+                       if (!cn.target && this.config.target) cn.target = this.config.target;
+                       if (cn._hc && !cn._io && this.config.useCookies) cn._io = this.isOpen(cn.id);
+                       if (!this.config.folderLinks && cn._hc) cn.url = null;
+                       if (this.config.useSelection && cn.id == this.selectedNode && !this.selectedFound) {
+                                       cn._is = true;
+                                       this.selectedNode = n;
+                                       this.selectedFound = true;
+                       }
+                       str += this.node(cn, n);
+                       if (cn._ls) break;
+               }
+       }
+       return str;
+};
+
+dTree.prototype.node = function(node, nodeId) {
+       var str = '<div class="dTreeNode">' + this.indent(node, nodeId);
+       if (this.config.useIcons) {
+               if (!node.icon) node.icon = (this.root.id == node.pid) ? this.icon.root : ((node._hc) ? this.icon.folder : this.icon.node);
+               if (!node.iconOpen) node.iconOpen = (node._hc) ? this.icon.folderOpen : this.icon.node;
+               if (this.root.id == node.pid) {
+                       node.icon = this.icon.root;
+                       node.iconOpen = this.icon.root;
+               }
+               str += '<img id="i' + this.obj + nodeId + '" src="' + ((node._io) ? node.iconOpen : node.icon) + '" alt="" />';
+       }
+       if (node.url) {
+               str += '<a id="s' + this.obj + nodeId + '" class="' + ((this.config.useSelection) ? ((node._is ? 'nodeSel' : 'node')) : 'node') + '" href="' + node.url + '"';
+               if (node.title) str += ' title="' + node.title + '"';
+               if (node.target) str += ' target="' + node.target + '"';
+               if (this.config.useStatusText) str += ' onmouseover="window.status=\'' + node.name + '\';return true;" onmouseout="window.status=\'\';return true;" ';
+               if (this.config.useSelection && ((node._hc && this.config.folderLinks) || !node._hc))
+                       str += ' onclick="javascript: ' + this.obj + '.s(' + nodeId + ');"';
+               str += '>';
+       }
+       else if ((!this.config.folderLinks || !node.url) && node._hc && node.pid != this.root.id)
+               str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');" class="node">';
+       str += node.name;
+       if (node.url || ((!this.config.folderLinks || !node.url) && node._hc)) str += '</a>';
+       str += '</div>';
+       if (node._hc) {
+               str += '<div id="d' + this.obj + nodeId + '" class="clip" style="display:' + ((this.root.id == node.pid || node._io) ? 'block' : 'none') + ';">';
+               str += this.addNode(node);
+               str += '</div>';
+       }
+       this.aIndent.pop();
+       return str;
+};
+
+dTree.prototype.indent = function(node, nodeId) {
+       var str = '';
+       if (this.root.id != node.pid) {
+               for (var n=0; n<this.aIndent.length; n++)
+                       str += '<img src="' + ( (this.aIndent[n] == 1 && this.config.useLines) ? this.icon.line : this.icon.empty ) + '" alt="" />';
+               (node._ls) ? this.aIndent.push(0) : this.aIndent.push(1);
+               if (node._hc) {
+                       str += '<a href="javascript: ' + this.obj + '.o(' + nodeId + ');"><img  id="j' + this.obj + nodeId + '" src="';
+                       if (!this.config.useLines) str += (node._io) ? this.icon.nlMinus : this.icon.nlPlus;
+                       else str += ( (node._io) ? ((node._ls && this.config.useLines) ? this.icon.minusBottom : this.icon.minus) : ((node._ls && this.config.useLines) ? this.icon.plusBottom : this.icon.plus ) );
+                       str += '" alt="" /></a>';
+               } else str += '<img src="' + ( (this.config.useLines) ? ((node._ls) ? this.icon.joinBottom : this.icon.join ) : this.icon.empty) + '" alt="" />';
+       }
+       return str;
+};
+
+dTree.prototype.setCS = function(node) {
+       var lastId;
+       for (var n=0; n<this.aNodes.length; n++) {
+               if (this.aNodes[n].pid == node.id) node._hc = true;
+               if (this.aNodes[n].pid == node.pid) lastId = this.aNodes[n].id;
+       }
+       if (lastId==node.id) node._ls = true;
+};
+
+dTree.prototype.getSelected = function() {
+       var sn = this.getCookie('cs' + this.obj);
+       return (sn) ? sn : null;
+};
+
+dTree.prototype.s = function(id) {
+       if (!this.config.useSelection) return;
+       var cn = this.aNodes[id];
+       if (cn._hc && !this.config.folderLinks) return;
+       if (this.selectedNode != id) {
+               if (this.selectedNode || this.selectedNode==0) {
+                       eOld = document.getElementById("s" + this.obj + this.selectedNode);
+                       eOld.className = "node";
+               }
+               eNew = document.getElementById("s" + this.obj + id);
+               eNew.className = "nodeSel";
+               this.selectedNode = id;
+               if (this.config.useCookies) this.setCookie('cs' + this.obj, cn.id);
+       }
+};
+
+dTree.prototype.o = function(id) {
+       var cn = this.aNodes[id];
+       this.nodeStatus(!cn._io, id, cn._ls);
+       cn._io = !cn._io;
+       if (this.config.closeSameLevel) this.closeLevel(cn);
+       if (this.config.useCookies) this.updateCookie();
+};
+
+dTree.prototype.oAll = function(status) {
+       for (var n=0; n<this.aNodes.length; n++) {
+               if (this.aNodes[n]._hc && this.aNodes[n].pid != this.root.id) {
+                       this.nodeStatus(status, n, this.aNodes[n]._ls)
+                       this.aNodes[n]._io = status;
+               }
+       }
+       if (this.config.useCookies) this.updateCookie();
+};
+
+dTree.prototype.openTo = function(nId, bSelect, bFirst) {
+       if (!bFirst) {
+               for (var n=0; n<this.aNodes.length; n++) {
+                       if (this.aNodes[n].id == nId) {
+                               nId=n;
+                               break;
+                       }
+               }
+       }
+       var cn=this.aNodes[nId];
+       if (cn.pid==this.root.id || !cn._p) return;
+       cn._io = true;
+       cn._is = bSelect;
+       if (this.completed && cn._hc) this.nodeStatus(true, cn._ai, cn._ls);
+       if (this.completed && bSelect) this.s(cn._ai);
+       else if (bSelect) this._sn=cn._ai;
+       this.openTo(cn._p._ai, false, true);
+};
+
+dTree.prototype.closeLevel = function(node) {
+       for (var n=0; n<this.aNodes.length; n++) {
+               if (this.aNodes[n].pid == node.pid && this.aNodes[n].id != node.id && this.aNodes[n]._hc) {
+                       this.nodeStatus(false, n, this.aNodes[n]._ls);
+                       this.aNodes[n]._io = false;
+                       this.closeAllChildren(this.aNodes[n]);
+               }
+       }
+}
+
+dTree.prototype.closeAllChildren = function(node) {
+       for (var n=0; n<this.aNodes.length; n++) {
+               if (this.aNodes[n].pid == node.id && this.aNodes[n]._hc) {
+                       if (this.aNodes[n]._io) this.nodeStatus(false, n, this.aNodes[n]._ls);
+                       this.aNodes[n]._io = false;
+                       this.closeAllChildren(this.aNodes[n]);          
+               }
+       }
+}
+
+dTree.prototype.nodeStatus = function(status, id, bottom) {
+       eDiv    = document.getElementById('d' + this.obj + id);
+       eJoin   = document.getElementById('j' + this.obj + id);
+       if (this.config.useIcons) {
+               eIcon   = document.getElementById('i' + this.obj + id);
+               eIcon.src = (status) ? this.aNodes[id].iconOpen : this.aNodes[id].icon;
+       }
+       eJoin.src = (this.config.useLines)?
+       ((status)?((bottom)?this.icon.minusBottom:this.icon.minus):((bottom)?this.icon.plusBottom:this.icon.plus)):
+       ((status)?this.icon.nlMinus:this.icon.nlPlus);
+       eDiv.style.display = (status) ? 'block': 'none';
+};
+
+
+dTree.prototype.clearCookie = function() {
+       var now = new Date();
+       var yesterday = new Date(now.getTime() - 1000 * 60 * 60 * 24);
+       this.setCookie('co'+this.obj, 'cookieValue', yesterday);
+       this.setCookie('cs'+this.obj, 'cookieValue', yesterday);
+};
+
+dTree.prototype.setCookie = function(cookieName, cookieValue, expires, path, domain, secure) {
+       document.cookie =
+               escape(cookieName) + '=' + escape(cookieValue)
+               + (expires ? '; expires=' + expires.toGMTString() : '')
+               + (path ? '; path=' + path : '')
+               + (domain ? '; domain=' + domain : '')
+               + (secure ? '; secure' : '');
+};
+
+dTree.prototype.getCookie = function(cookieName) {
+       var cookieValue = '';
+       var posName = document.cookie.indexOf(escape(cookieName) + '=');
+       if (posName != -1) {
+               var posValue = posName + (escape(cookieName) + '=').length;
+               var endPos = document.cookie.indexOf(';', posValue);
+               if (endPos != -1) cookieValue = unescape(document.cookie.substring(posValue, endPos));
+               else cookieValue = unescape(document.cookie.substring(posValue));
+       }
+       return (cookieValue);
+};
+
+dTree.prototype.updateCookie = function() {
+       var str = '';
+       for (var n=0; n<this.aNodes.length; n++) {
+               if (this.aNodes[n]._io && this.aNodes[n].pid != this.root.id) {
+                       if (str) str += '.';
+                       str += this.aNodes[n].id;
+               }
+       }
+       this.setCookie('co' + this.obj, str);
+};
+
+dTree.prototype.isOpen = function(id) {
+       var aOpen = this.getCookie('co' + this.obj).split('.');
+       for (var n=0; n<aOpen.length; n++)
+               if (aOpen[n] == id) return true;
+       return false;
+};
+
+if (!Array.prototype.push) {
+       Array.prototype.push = function array_push() {
+               for(var i=0;i<arguments.length;i++)
+                       this[this.length]=arguments[i];
+               return this.length;
+       }
+};
+if (!Array.prototype.pop) {
+       Array.prototype.pop = function array_pop() {
+               lastElement = this[this.length-1];
+               this.length = Math.max(this.length-1,0);
+               return lastElement;
+       }
+};
diff --git a/Open-ILS/web/opac/common/js/fmcore.js b/Open-ILS/web/opac/common/js/fmcore.js
new file mode 100644 (file)
index 0000000..714e1f7
--- /dev/null
@@ -0,0 +1,8 @@
+var _c = {};
+_c["perm_ex"] = ["err_msg","type",];
+_c["au"] = ["addresses","cards","checkouts","hold_requests","settings","stat_cat_entries","survey_responses","active","alert_message","billing_address","card","claims_returned_count","create_date","credit_forward_balance","day_phone","dob","email","evening_phone","expire_date","family_name","first_given_name","home_ou","id","ident_type","ident_type2","ident_value","ident_value2","last_xact_id","mailing_address","master_account","net_access_level","other_phone","passwd","photo_url","prefix","profile","second_given_name","standing","suffix","super_user","usrgroup","usrname",];
+_c["ex"] = ["err_msg","type",];
+_c["mvr"] = ["author","call_numbers","copy_count","doc_id","doc_type","edition","isbn","online_loc","pubdate","publisher","serials","series","subject","synopsis","tcn","title","types_of_resource",];
+_c["aou"] = ["children","billing_address","holds_address","id","ill_address","mailing_address","name","ou_type","parent_ou","shortname",];
+_c["aout"] = ["children","can_have_users","can_have_vols","depth","id","name","opac_label","parent",];
+fmclasses = _c;
diff --git a/Open-ILS/web/opac/common/js/fmgen.js b/Open-ILS/web/opac/common/js/fmgen.js
new file mode 100644 (file)
index 0000000..72886cc
--- /dev/null
@@ -0,0 +1,64 @@
+/* generate fieldmapper javascript classes.  This expects a global variable
+       called 'fmclasses' to be fleshed with the classes we need to build */
+
+function Fieldmapper() {}
+
+var errorstr = "Attempt to build fieldmapper object with non-array";
+
+Fieldmapper.prototype.clone = function() {
+       var obj = new this.constructor();
+
+       for( var i in this.a ) {
+               var thing = this.a[i];
+               if(thing == null) continue;
+
+               if( thing._isfieldmapper ) {
+                       obj.a[i] = thing.clone();
+               } else {
+
+                       if(instanceOf(thing, Array)) {
+                               obj.a[i] = new Array();
+
+                               for( var j in thing ) {
+
+                                       if( thing[j]._isfieldmapper )
+                                               obj.a[i][j] = thing[j].clone();
+                                       else
+                                               obj.a[i][j] = thing[j];
+                               }
+                       } else {
+                               obj.a[i] = thing;
+                       }
+               }
+       }
+       return obj;
+}
+Fieldmapper.prototype.isnew = function(n) { if(arguments.length == 1) this.a[0] =n; return this.a[0]; }
+Fieldmapper.prototype.ischanged = function(n) { if(arguments.length == 1) this.a[1] =n; return this.a[1]; }
+Fieldmapper.prototype.isdeleted = function(a) { if(arguments.length == 1) this.a[2] =n; return this.a[2]; }
+function FMEX(message) { this.message = message; }
+FMEX.toString = function() { return "FieldmapperException: " + this.message + "\n"; }
+
+var string = "";
+for( var cl in fmclasses ) {
+       string += cl + ".prototype = new Fieldmapper(); " + 
+                                               cl + ".prototype.constructor = " + cl + ";" +
+                                               cl + ".baseClass = Fieldmapper.constructor;" +
+                                               "function " + cl + "(a) { " +
+                                                       "this.classname = \"" + cl + "\";" +
+                                                       "this._isfieldmapper = true;" +
+                                                       "if(a) { if(a.constructor == Array) this.a = a; else throw new FMEX(errorstr);} else this.a = []}"; 
+
+       string += cl + "._isfieldmapper=true;";
+
+       for( var pos in fmclasses[cl] ) {
+               var p = parseInt(pos) + 3;
+               var field = fmclasses[cl][pos];
+               string += cl + ".prototype." + field + 
+                       "=function(n){if(arguments.length == 1)this.a[" + 
+                       p + "]=n;return this.a[" + p + "];};";
+       }
+}
+eval(string);
+
+
diff --git a/Open-ILS/web/opac/common/js/init.js b/Open-ILS/web/opac/common/js/init.js
new file mode 100644 (file)
index 0000000..a199dc3
--- /dev/null
@@ -0,0 +1,21 @@
+
+/* these events should be used by all */
+
+window.onunload = windowUnload;
+
+attachEvt("common", "init", loadUIObjects);
+attachEvt("common", "init", initParams);
+attachEvt("common", "init", drawOrgTree); 
+attachEvt("common", "unload", _tree_killer);
+attachEvt("common", "unload", clearUIObjects);
+attachEvt("common", "unload", cleanRemoteRequests);
+
+function init() {
+       runEvt('common','init');
+       switch(findCurrentPage()) {
+               case MRESULT: runEvt('mresult', 'run'); break;
+               case RRESULT: runEvt('rresult', 'run'); break;
+       }
+}
+
+function windowUnload() { runEvt("common", "unload"); }
diff --git a/Open-ILS/web/opac/common/js/md5.js b/Open-ILS/web/opac/common/js/md5.js
new file mode 100644 (file)
index 0000000..46d2aab
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+ * Digest Algorithm, as defined in RFC 1321.
+ * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for more info.
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
+var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
+var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
+function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
+function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
+function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
+function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
+function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function md5_vm_test()
+{
+  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
+}
+
+/*
+ * Calculate the MD5 of an array of little-endian words, and a bit length
+ */
+function core_md5(x, len)
+{
+  /* append padding */
+  x[len >> 5] |= 0x80 << ((len) % 32);
+  x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+  var a =  1732584193;
+  var b = -271733879;
+  var c = -1732584194;
+  var d =  271733878;
+
+  for(var i = 0; i < x.length; i += 16)
+  {
+    var olda = a;
+    var oldb = b;
+    var oldc = c;
+    var oldd = d;
+
+    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
+    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
+    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
+    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
+    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
+    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
+    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
+    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
+    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
+    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
+    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
+    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
+    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
+    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
+    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
+    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
+
+    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
+    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
+    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
+    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
+    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
+    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
+    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
+    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
+    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
+    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
+    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
+    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
+    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
+    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
+    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
+    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
+
+    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
+    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
+    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
+    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
+    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
+    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
+    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
+    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
+    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
+    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
+    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
+    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
+    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
+    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
+    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
+    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
+
+    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
+    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
+    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
+    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
+    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
+    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
+    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
+    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
+    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
+    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
+    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
+    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
+    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
+    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
+    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
+    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
+
+    a = safe_add(a, olda);
+    b = safe_add(b, oldb);
+    c = safe_add(c, oldc);
+    d = safe_add(d, oldd);
+  }
+  return Array(a, b, c, d);
+
+}
+
+/*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+function md5_cmn(q, a, b, x, s, t)
+{
+  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
+}
+function md5_ff(a, b, c, d, x, s, t)
+{
+  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+function md5_gg(a, b, c, d, x, s, t)
+{
+  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+function md5_hh(a, b, c, d, x, s, t)
+{
+  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+}
+function md5_ii(a, b, c, d, x, s, t)
+{
+  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+/*
+ * Calculate the HMAC-MD5, of a key and some data
+ */
+function core_hmac_md5(key, data)
+{
+  var bkey = str2binl(key);
+  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
+
+  var ipad = Array(16), opad = Array(16);
+  for(var i = 0; i < 16; i++)
+  {
+    ipad[i] = bkey[i] ^ 0x36363636;
+    opad[i] = bkey[i] ^ 0x5C5C5C5C;
+  }
+
+  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
+  return core_md5(opad.concat(hash), 512 + 128);
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+  return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+  return (num << cnt) | (num >>> (32 - cnt));
+}
+
+/*
+ * Convert a string to an array of little-endian words
+ * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
+ */
+function str2binl(str)
+{
+  var bin = Array();
+  var mask = (1 << chrsz) - 1;
+  for(var i = 0; i < str.length * chrsz; i += chrsz)
+    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
+  return bin;
+}
+
+/*
+ * Convert an array of little-endian words to a string
+ */
+function binl2str(bin)
+{
+  var str = "";
+  var mask = (1 << chrsz) - 1;
+  for(var i = 0; i < bin.length * 32; i += chrsz)
+    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
+  return str;
+}
+
+/*
+ * Convert an array of little-endian words to a hex string.
+ */
+function binl2hex(binarray)
+{
+  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+  var str = "";
+  for(var i = 0; i < binarray.length * 4; i++)
+  {
+    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
+           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
+  }
+  return str;
+}
+
+/*
+ * Convert an array of little-endian words to a base-64 string
+ */
+function binl2b64(binarray)
+{
+  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  var str = "";
+  for(var i = 0; i < binarray.length * 4; i += 3)
+  {
+    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
+                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
+                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
+    for(var j = 0; j < 4; j++)
+    {
+      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
+      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
+    }
+  }
+  return str;
+}
diff --git a/Open-ILS/web/opac/common/js/opac_utils.js b/Open-ILS/web/opac/common/js/opac_utils.js
new file mode 100644 (file)
index 0000000..30dfe77
--- /dev/null
@@ -0,0 +1,431 @@
+var IAMXUL = false;
+function isXUL() { return IAMXUL; }
+
+
+/* - Request ------------------------------------------------------------- */
+function Request(type) {
+       var s = type.split(":");
+       if(s[2] == "1" && isXUL()) s[1] += ".staff";
+       this.request = new RemoteRequest(s[0], s[1]);
+       for( var x = 1; x!= arguments.length; x++ ) 
+               this.request.addParam(arguments[x]);
+}
+
+Request.prototype.callback = function(cal) { this.request.setCompleteCallback(cal); }
+Request.prototype.send         = function(block){this.request.send(block);}
+Request.prototype.result       = function(){return this.request.getResultObject();}
+/* ----------------------------------------------------------------------- */
+
+function showCanvas() { setTimeout(_showCanvas, 200); }
+function _showCanvas() {
+       for( var x in G.ui.altcanvas ) {
+               hideMe(G.ui.altcanvas[x]);
+       }
+       hideMe(G.ui.common.loading);
+       unHideMe(G.ui.common.canvas_main);
+       G.ui.searchbar.text.focus(); 
+}
+
+var newCanvasNode;
+function swapCanvas(newNode) { newCanvasNode = newNode; setTimeout(_swapCanvas, 200); }
+function _swapCanvas() {
+       for( var x in G.ui.altcanvas ) 
+               hideMe(G.ui.altcanvas[x]);
+
+       hideMe(G.ui.common.loading);
+       hideMe(G.ui.common.canvas_main);
+       unHideMe(newCanvasNode);
+}
+
+/* finds the name of the current page */
+var currentPage = null;
+function findCurrentPage() {
+       if(currentPage) return currentPage;
+
+       var pages = [];
+       for( var p in config.page ) pages.push(config.page[p]);
+       pages = pages.sort( function(a,b){ return - (a.length - b.length); } );
+
+       var path = location.pathname;
+       if(!path.match(/.*\.xml$/))
+               path += "index.xml"; /* in case they go to  / */
+
+       var page = null;
+       for( var p in pages ) {
+               if( path.indexOf(pages[p]) != -1)
+                       page = pages[p];
+       }
+
+       for( var p in config.page ) {
+               if(config.page[p] == page) {
+                       currentPage = p;
+                       return p;
+               }
+       }
+
+       return null;
+}
+
+
+/* sets all of the params values  ----------------------------- */
+var TERM,  STYPE,  LOCATION,  DEPTH,  FORM, OFFSET,  COUNT,  
+        HITCOUNT,  RANKS, SEARCHBAR_EXTRAS;
+
+function initParams() {
+       var cgi = new CGI();    
+
+       TERM    = cgi.param(PARAM_TERM);
+       STYPE   = cgi.param(PARAM_STYPE);
+       FORM    = cgi.param(PARAM_FORM);
+
+       LOCATION        = parseInt(cgi.param(PARAM_LOCATION));
+       DEPTH           = parseInt(cgi.param(PARAM_DEPTH));
+       OFFSET  = parseInt(cgi.param(PARAM_OFFSET));
+       COUNT           = parseInt(cgi.param(PARAM_COUNT));
+       HITCOUNT        = parseInt(cgi.param(PARAM_HITCOUNT));
+       MRID            = parseInt(cgi.param(PARAM_MRID));
+       RID             = parseInt(cgi.param(PARAM_RID));
+
+       /* set up some sane defaults */
+       if(isNaN(LOCATION))     LOCATION        = 1;
+       if(isNaN(DEPTH))                DEPTH           = 0;
+       if(isNaN(OFFSET))               OFFSET  = 0;
+       if(isNaN(COUNT))                COUNT           = 10;
+       if(isNaN(HITCOUNT))     HITCOUNT        = 0;
+       if(isNaN(SEARCHBAR_EXTRAS))     SEARCHBAR_EXTRAS        = 0;
+       if(isNaN(MRID))         MRID            = 0;
+       if(isNaN(RID))                  RID             = 0;
+}
+
+/* URL param accessors */
+function getTerm(){return TERM;}
+function getStype(){return STYPE;}
+function getLocation(){return LOCATION;}
+function getDepth(){return DEPTH;}
+function getForm(){return FORM;}
+function getOffset(){return OFFSET;}
+function getDisplayCount(){return COUNT;}
+function getHitCount(){return HITCOUNT;}
+function getSearchBarExtras(){return SEARCHBAR_EXTRAS;}
+function getMrid(){return MRID;};
+function getRid(){return RID;};
+
+
+
+/* builds an opac URL.  If no page is defined, the current page is used
+       if slim, then only everything after the ? is returned (no host portion) */
+function findBasePath() {
+       var path = location.pathname;
+       if(!path.match(/.*\.xml$/)) path += "index.xml"; 
+       var idx = path.indexOf(config.page[findCurrentPage()]);
+       return path.substring(0, idx);
+}
+
+function findBaseURL(ssl) {
+       var path = findBasePath();
+       var proto = location.protocol;
+       if(ssl) proto = "https";
+       return location.protocol + "//" + location.host + path;
+}
+
+function buildImageLink(name, ssl) {
+       return findBaseURL(ssl) + "../../../images/" + name;
+}
+
+function  buildOPACLink(args, slim, ssl) {
+
+       if(!args) args = {};
+       var string = "";
+
+       if(!slim) {
+               string = findBaseURL(ssl);
+               if(args.page) string += config.page[args.page];
+               else string += config.page[findCurrentPage()];
+       }
+
+       string += "?";
+
+       for( var x in args ) {
+               if(x == "page" || args[x] == null) continue;
+               string += "&" + x + "=" + encodeURIComponent(args[x]);
+       }
+
+       string += _appendParam(TERM,            PARAM_TERM, args, getTerm, string);
+       string += _appendParam(STYPE,           PARAM_STYPE, args, getStype, string);
+       string += _appendParam(LOCATION, PARAM_LOCATION, args, getLocation, string);
+       string += _appendParam(DEPTH,           PARAM_DEPTH, args, getDepth, string);
+       string += _appendParam(FORM,            PARAM_FORM, args, getForm, string);
+       string += _appendParam(OFFSET,  PARAM_OFFSET, args, getOffset, string);
+       string += _appendParam(COUNT,           PARAM_COUNT, args, getDisplayCount, string);
+       string += _appendParam(HITCOUNT, PARAM_HITCOUNT, args, getHitCount, string);
+       string += _appendParam(MRID,            PARAM_MRID, args, getMrid, string);
+       string += _appendParam(RID,             PARAM_RID, args, getRid, string);
+       return string.replace(/\&$/,'').replace(/\?\&/,"?");    
+}
+
+function _appendParam( fieldVar, fieldName, overrideArgs, getFunc, string ) {
+       var ret = "";
+       if( fieldVar != null && overrideArgs[fieldName] == null ) 
+               ret = "&" + fieldName + "=" + encodeURIComponent(getFunc());
+       return ret;
+}
+
+
+function EX(message) { this.init(message); }
+EX.prototype.init = function(message) { this.message = message; }
+EX.prototype.toString = function() { return "\n *** Exception Occured \n" + this.message; }  
+EXCommunication.prototype              = new EX();
+EXCommunication.prototype.constructor  = EXCommunication;
+EXCommunication.baseClass              = EX.prototype.constructor;
+function EXCommunication(message) { this.init("EXCommunication: " + message); }                          
+
+/* ----------------------------------------------------------------------- */
+function cleanISBN(isbn) {
+   if(isbn) {
+      isbn = isbn.toString().replace(/^\s+/,"");
+      var idx = isbn.indexOf(" ");
+      if(idx > -1) { isbn = isbn.substring(0, idx); }
+   } else isbn = "";
+   return isbn;
+}       
+
+
+
+
+/* builds a link that goes to the title listings for a metarecord */
+function buildTitleLink(rec, link) {
+       if(!rec) return;
+       link.appendChild(text(normalize(truncate(rec.title(), 65))));
+       var args = {};
+       args.page = RRESULT;
+       args[PARAM_OFFSET] = 0;
+       args[PARAM_MRID] = rec.doc_id();
+       link.setAttribute("href", buildOPACLink(args));
+}
+
+function buildTitleDetailLink(rec, link) {
+       if(!rec) return;
+       link.appendChild(text(normalize(truncate(rec.title(), 65))));
+       var args = {};
+       args.page = RDETAIL;
+       args[PARAM_OFFSET] = 0;
+       args[PARAM_RID] = rec.doc_id();
+       link.setAttribute("href", buildOPACLink(args));
+}
+
+/* 'type' is one of STYPE_AUTHOR, STYPE_SUBJECT, ... found in config.js 
+       'trunc' is the number of characters to show in the string, defaults to 65 */
+function buildSearchLink(type, string, linknode, trunc) {
+       if(!trunc) trunc = 65;
+       var args = {};
+       args.page = MRESULT;
+       args[PARAM_OFFSET] = 0;
+       args[PARAM_TERM] = string;
+       args[PARAM_STYPE] = type;
+       linknode.appendChild(text(normalize(truncate(string, trunc))));
+       linknode.setAttribute("href", buildOPACLink(args));
+}
+
+
+/* ----------------------------------------------------------------------- */
+/* user session handling */
+/* ----------------------------------------------------------------------- */
+
+/* session is the login session.  If no session is provided, we attempt
+       to find one in the cookies.  If 'force' is true we retrieve the 
+       user from the server even if there is already a global user present.
+       if ses != G.user.session, we also force a grab */
+var cookie = new cookieObject("ses", 1, "/", COOKIE_SES);
+function grabUser(ses, force) {
+
+       if(!ses) ses = cookie.get(COOKIE_SES);
+       if(!ses) return false;
+
+       if(!force) 
+               if(G.user && G.user.session == ses)
+                       return G.user;
+
+       /* first make sure the session is valid */
+       var request = new Request(FETCH_SESSION, ses );
+       request.send(true);
+       var user = request.result();
+       if( !(typeof user == 'object' && user._isfieldmapper) ) {
+               return false;
+       }
+
+       G.user = user;
+       G.user.fleshed = false;
+       G.user.session = ses;
+       cookie.put(COOKIE_SES, ses);
+       cookie.write();
+
+       return G.user;
+
+}
+
+function grabFleshedUser() {
+
+       if(!G.user || !G.user.session) {
+               grabUser();     
+               if(!G.user || !G.user.session) return null;
+       }
+
+       if(G.user.fleshed) return G.user;
+
+   var req = new Request(FETCH_FLESHED_USER, G.user.session);
+       req.send(true);
+
+       G.user = req.result();
+
+       if(!G.user || G.user.length == 0) { 
+               G.user = null; return false; 
+               cookie.remove(COOKIE_SES);
+       }
+
+       G.user.session = ses;
+       G.user.fleshed = true;
+
+       cookie.put(COOKIE_SES, ses); /*  update the cookie */
+       cookie.write();
+
+       return G.user;
+}
+
+
+/* returns a fleshed G.user on success, false on failure */
+function doLogin() {
+
+       var uname = G.ui.login.username.value;
+       var passwd = G.ui.login.password.value; 
+
+       var init_request = new Request( LOGIN_INIT, uname );
+   init_request.send(true);
+   var seed = init_request.result();
+
+   if( ! seed || seed == '0') {
+      alert( "Error Communicating with Authentication Server" );
+      return null;
+   }
+
+   var auth_request = new Request( LOGIN_COMPLETE, 
+               uname, hex_md5(seed + hex_md5(passwd)), "opac");
+
+   auth_request.send(true);
+   var auth_result = auth_request.result();
+
+   if(auth_result == '0' || auth_result == null || auth_result.length == 0) { return false; }
+
+       var u = grabUser(auth_result, true);
+       if(u) updateLoc(u.home_ou(), findOrgDepth(u.home_ou()));
+
+       return u;
+}
+
+function doLogout() {
+
+       /* be nice and delete the session from the server */
+       if(G.user && G.user.session) { 
+               var req = new Request(LOGIN_DELETE, G.user.session);
+      req.send(true);
+               try { req.result(); } catch(E){}
+    }
+
+       G.user = null;
+       cookie.remove(COOKIE_SES);
+
+       hideMe(G.ui.sidebar.logoutbox);
+       unHideMe(G.ui.sidebar.loginbox);
+       hideMe(G.ui.sidebar.logged_in_as);
+
+}
+
+
+function hideMe(obj) { addCSSClass(obj, config.css.hide_me); } 
+function unHideMe(obj) { removeCSSClass(obj, config.css.hide_me); }
+
+
+/* ----------------------------------------------------------------------- */
+/* build the org tree */
+/* ----------------------------------------------------------------------- */
+
+
+function drawOrgTree() {
+       G.ui.common.org_tree.innerHTML = buildOrgSelector().toString();
+}
+       
+var orgTreeSelector;
+function buildOrgSelector() {
+       var tree = new dTree("orgTreeSelector"); 
+       for( var i in orgArraySearcher ) { 
+               var node = orgArraySearcher[i];
+               if( node == null ) continue;
+               if(node.parent_ou() == null)
+                       tree.add(node.id(), -1, node.name(), 
+                               "javascript:orgSelect(" + node.id() + ");", node.name());
+               else {
+                       tree.add(node.id(), node.parent_ou().id(), node.name(), 
+                               "javascript:orgSelect(" + node.id() + ");", node.name());
+               }
+       }
+       orgTreeSelector = tree;
+       return tree;
+}
+
+function orgSelect(id) {
+       showCanvas();
+       updateLoc(id, findOrgDepth(id));
+}
+
+
+/* ------------------------------------------------------------------------------------------------------ */
+/* org tree utilities */
+/* ------------------------------------------------------------------------------------------------------ */
+
+/* takes an org unit or id and return the numeric depth */
+function findOrgDepth(org_id_or_node) {
+       return findOrgType(findOrgUnit(org_id_or_node).ou_type()).depth();
+}
+
+/* takes the org type id from orgunit.ou_type() field and returns
+       the org type object */
+function findOrgType(type_id) {
+       if(typeof type_id == 'object') return type_id;
+       for(var type in globalOrgTypes) {
+               var t =globalOrgTypes[type]; 
+               if( t.id() == type_id || t.id() == parseInt(type_id) ) 
+                       return t;
+       }
+       return null;
+}
+
+
+/* returns an org unit by id.  if an object is passed in as the id,
+       then the object is assumed to be an org unit and is returned */
+function findOrgUnit(org_id) {
+       return (typeof org_id == 'object') ? org_id : orgArraySearcher[org_id];
+}
+
+
+/* builds a trail from the top of the org tree to the node provide.
+       basically fleshes out 'my orgs' 
+       Returns an array of [org0, org1, ..., myorg] */
+function orgNodeTrail(node) {
+       var na = new Array();
+       while( node ) {
+               na.push(node);
+               node = findOrgUnit(node.parent_ou());
+       }
+       return na.reverse();
+}
+
+
+/* returns an array of sibling org units */
+function findSiblingOrgs(node) { return findOrgUnit(node.parent_ou()).children(); }
+/* ------------------------------------------------------------------------------------------------------ */
+
+
+
+
+
+
+
diff --git a/Open-ILS/web/opac/common/js/utils.js b/Open-ILS/web/opac/common/js/utils.js
new file mode 100644 (file)
index 0000000..499694b
--- /dev/null
@@ -0,0 +1,272 @@
+function getId(id) {
+       return document.getElementById(id);
+}
+
+
+function addCSSClass(e,c) {
+       if(!e || !c) return;
+
+       var css_class_string = e.className;
+       var css_class_array;
+
+       if(css_class_string)
+               css_class_array = css_class_string.split(/\s+/);
+
+       var string_ip = ""; /*strip out nulls*/
+       for (var css_class in css_class_array) {
+               if (css_class_array[css_class] == c) { return; }
+               if(css_class_array[css_class] !=null)
+                       string_ip += css_class_array[css_class] + " ";
+       }
+       string_ip = string_ip + c;
+       e.className = string_ip;
+}
+
+function removeCSSClass(e, c) {
+       if(!e || !c) return;
+
+       var css_class_string = '';
+
+       var css_class_array = e.className;
+       if( css_class_array )
+               css_class_array = css_class_array.split(/\s+/);
+
+       var first = 1;
+       for (var css_class in css_class_array) {
+               if (css_class_array[css_class] != c) {
+                       if (first == 1) {
+                               css_class_string = css_class_array[css_class];
+                               first = 0;
+                       } else {
+                               css_class_string = css_class_string + ' ' +
+                                       css_class_array[css_class];
+                       }
+               }
+       }
+       e.className = css_class_string;
+}
+
+
+/*returns the character code pressed that caused the event */
+function grabCharCode(evt) {
+   evt = (evt) ? evt : ((window.event) ? event : null); 
+   if( evt ) {
+      return (evt.charCode ? evt.charCode : 
+         ((evt.which) ? evt.which : evt.keyCode ));
+   } else { return -1; }
+}       
+
+
+/* returns true if the user pressed enter */
+function userPressedEnter(evt) {
+   var code = grabCharCode(evt);
+   if(code==13||code==3) return true;
+   return false;
+}   
+
+
+function goTo(url) {location.href = url;}
+
+
+function removeChildren(dom) {
+       if(!dom) return;
+       while(dom.childNodes[0])
+               dom.removeChild(dom.childNodes[0]);
+}
+
+
+function instanceOf(object, constructorFunction) {
+
+   if(!IE) {
+      while (object != null) {
+         if (object == constructorFunction.prototype)
+            return true;
+         object = object.__proto__;
+      }
+   } else {
+      while(object != null) {
+         if( object instanceof constructorFunction )
+            return true;
+         object = object.__proto__;
+      }
+   }
+   return false;
+}         
+
+
+/* ------------------------------------------------------------------------------------------- */
+/* detect my browser */
+var isMac, NS, NS4, NS6, IE, IE4, IE4mac, IE4plus, IE5, IE5plus, IE6, IEMajor, ver4;
+function detect_browser() {       
+
+   isMac = (navigator.appVersion.indexOf("Mac")!=-1) ? true : false;
+   NS = (navigator.appName == "Netscape") ? true : false;
+   NS4 = (document.layers) ? true : false;
+   IE = (navigator.appName == "Microsoft Internet Explorer") ? true : false;
+   IEmac = ((document.all)&&(isMac)) ? true : false;
+   IE4plus = (document.all) ? true : false;
+   IE4 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 4.")!=-1)) ? true : false;
+   IE5 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 5.")!=-1)) ? true : false;
+   IE6 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 6.")!=-1)) ? true : false;
+   ver4 = (NS4 || IE4plus) ? true : false;
+   NS6 = (!document.layers) && (navigator.userAgent.indexOf('Netscape')!=-1)?true:false;
+
+   IE5plus = IE5 || IE6;
+   IEMajor = 0;
+
+   if (IE4plus) {
+      var start = navigator.appVersion.indexOf("MSIE");
+      var end = navigator.appVersion.indexOf(".",start);
+      IEMajor = parseInt(navigator.appVersion.substring(start+5,end));
+      IE5plus = (IEMajor>=5) ? true : false;
+   }
+}  
+detect_browser();
+/* ------------------------------------------------------------------------------------------- */
+
+
+function text(t) {
+       if(t == null) t = "";
+       return document.createTextNode(t);
+}
+
+function elem(name, attrs, text) {
+    var e = createAppElement(name);
+    if (attrs) {
+        for (key in attrs) {
+                         if( key == 'id') e.id = attrs[key];
+                         else e.setAttribute(key, attrs[key]);
+        }
+    }
+    if (text) e.appendChild(text(text));
+    return e;
+}                   
+
+
+/* sel is the selector object, sets selected on the 
+       option with the given value. case does not matter...*/
+function setSelector( sel, value ) {
+       if(sel && value != null) {
+               for( var i = 0; i!= sel.options.length; i++ ) { 
+                       if( sel.options[i] ) {
+                               var val = sel.options[i].value;
+                               value += ""; /* in case of number */ 
+                               if( val && val.toLowerCase() == value.toLowerCase() ) {
+                                       sel.selectedIndex = i;
+                                       sel.options[i].selected = true;
+                               }
+                       }
+               }
+       }
+}
+
+
+/* split on spaces.  capitalize the first /\w/ character in
+   each substring */
+function normalize(val) {
+
+   if(!val) return ""; 
+
+   var newVal = '';
+   try {val = val.split(' ');} catch(E) {return val;}
+   var reg = /\w/;
+
+   for( var c = 0; c < val.length; c++) {
+
+      var string = val[c];
+      var cap = false; 
+      for(var x = 0; x != string.length; x++) {
+
+         if(!cap) {
+            var ch = string.charAt(x);
+            if(reg.exec(ch + "")) {
+               newVal += string.charAt(x).toUpperCase();
+               cap = true;
+               continue;
+            }
+         }
+
+         newVal += string.charAt(x).toLowerCase();
+      }
+      if(c < (val.length-1)) newVal += " ";
+   }
+
+   newVal = newVal.replace(/\s*\.\s*$/,'');
+   newVal = newVal.replace(/\s*\/\s*\/\s*$/,' / ');
+   newVal = newVal.replace(/\s*\/\s*$/,'');
+
+   return newVal;
+}
+
+
+/* returns true if n is null or stringifies to 'undefined' */
+function isNull(n) {
+       if( n == null || n.toString().toLowerCase() == "undefined" 
+               || n.toString().toLowerCase() == "null" )
+               return true;
+       return false;
+}
+
+
+/* find nodes with an attribute of 'name' that equals nodeName */
+
+function findNodeByName(root, nodeName) {
+       if( !root || !nodeName) return null;
+
+       if(root.nodeType != 1) return null;
+
+       if(root.getAttribute("name") == nodeName ||
+                       root.name == nodeName ) {
+               return root;
+       }
+
+       var children = root.childNodes;
+
+       for( var i = 0; i != children.length; i++ ) {
+               var n = findNodeByName(children[i], nodeName);
+               if(n) return n;
+       }
+
+       return null;
+
+}
+
+
+/* truncates the string at 'size' characters and appends a '...' to the end */
+function truncate(string, size) {
+       if(string && size != null && 
+                       size > -1 && string.length > size) 
+               return string.substr(0, size) + "..."; 
+       return string;
+}
+
+
+/* style sheets must have a 'name' attribute for these functions to work */
+function setActiveStyleSheet(name) {
+       var i, a, main;
+       for (i = 0; (a = document.getElementsByTagName ("link")[i]); i++) {
+               if (a.getAttribute ("rel").indexOf ("style") != -1 && a.getAttribute ("name")) {
+                       if (a.getAttribute ("name").indexOf(name) != -1)
+                               a.disabled = false;
+               }
+       }
+}
+
+function swapStyleSheet(newname, oldname) {
+       var i, a, main;
+       for (i = 0; (a = document.getElementsByTagName ("link")[i]); i++) {
+               if (a.getAttribute ("rel").indexOf ("style") != -1 && a.getAttribute ("name")) {
+                       if (a.getAttribute ("name").indexOf(newsheet) != -1)
+                               a.disabled = false;
+                       if (a.getAttribute ("name").indexOf(oldsheet) != -1)
+                               a.disabled = true;
+               }
+       }
+}
+
+
+
+
+
+
+
diff --git a/Open-ILS/web/opac/images/main_logo.jpg b/Open-ILS/web/opac/images/main_logo.jpg
new file mode 100644 (file)
index 0000000..7b77a0a
Binary files /dev/null and b/Open-ILS/web/opac/images/main_logo.jpg differ
diff --git a/Open-ILS/web/opac/images/orgtree/base.gif b/Open-ILS/web/opac/images/orgtree/base.gif
new file mode 100644 (file)
index 0000000..9ac0b11
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/base.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/cd.gif b/Open-ILS/web/opac/images/orgtree/cd.gif
new file mode 100644 (file)
index 0000000..7503819
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/cd.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/empty.gif b/Open-ILS/web/opac/images/orgtree/empty.gif
new file mode 100644 (file)
index 0000000..b5cf523
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/empty.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/folder.gif b/Open-ILS/web/opac/images/orgtree/folder.gif
new file mode 100644 (file)
index 0000000..eb12976
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/folder.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/folderopen.gif b/Open-ILS/web/opac/images/orgtree/folderopen.gif
new file mode 100644 (file)
index 0000000..c5c3110
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/folderopen.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/globe.gif b/Open-ILS/web/opac/images/orgtree/globe.gif
new file mode 100644 (file)
index 0000000..57123d0
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/globe.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/imgfolder.gif b/Open-ILS/web/opac/images/orgtree/imgfolder.gif
new file mode 100644 (file)
index 0000000..e6d8803
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/imgfolder.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/join.gif b/Open-ILS/web/opac/images/orgtree/join.gif
new file mode 100644 (file)
index 0000000..34dd476
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/join.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/joinbottom.gif b/Open-ILS/web/opac/images/orgtree/joinbottom.gif
new file mode 100644 (file)
index 0000000..48b81c8
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/joinbottom.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/line.gif b/Open-ILS/web/opac/images/orgtree/line.gif
new file mode 100644 (file)
index 0000000..1a259ee
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/line.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/minus.gif b/Open-ILS/web/opac/images/orgtree/minus.gif
new file mode 100644 (file)
index 0000000..3d212a9
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/minus.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/minusbottom.gif b/Open-ILS/web/opac/images/orgtree/minusbottom.gif
new file mode 100644 (file)
index 0000000..dc3198b
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/minusbottom.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/musicfolder.gif b/Open-ILS/web/opac/images/orgtree/musicfolder.gif
new file mode 100644 (file)
index 0000000..f620789
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/musicfolder.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/nolines_minus.gif b/Open-ILS/web/opac/images/orgtree/nolines_minus.gif
new file mode 100644 (file)
index 0000000..2592ac2
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/nolines_minus.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/nolines_plus.gif b/Open-ILS/web/opac/images/orgtree/nolines_plus.gif
new file mode 100644 (file)
index 0000000..f258ce2
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/nolines_plus.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/page.gif b/Open-ILS/web/opac/images/orgtree/page.gif
new file mode 100644 (file)
index 0000000..42d7318
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/page.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/plus.gif b/Open-ILS/web/opac/images/orgtree/plus.gif
new file mode 100644 (file)
index 0000000..b2c9972
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/plus.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/plusbottom.gif b/Open-ILS/web/opac/images/orgtree/plusbottom.gif
new file mode 100644 (file)
index 0000000..b5671d8
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/plusbottom.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/question.gif b/Open-ILS/web/opac/images/orgtree/question.gif
new file mode 100644 (file)
index 0000000..dd4e685
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/question.gif differ
diff --git a/Open-ILS/web/opac/images/orgtree/trash.gif b/Open-ILS/web/opac/images/orgtree/trash.gif
new file mode 100644 (file)
index 0000000..cfa0f00
Binary files /dev/null and b/Open-ILS/web/opac/images/orgtree/trash.gif differ
diff --git a/Open-ILS/web/opac/images/small_logo.jpg b/Open-ILS/web/opac/images/small_logo.jpg
new file mode 100644 (file)
index 0000000..8cf76e2
Binary files /dev/null and b/Open-ILS/web/opac/images/small_logo.jpg differ
diff --git a/Open-ILS/web/opac/images/tor/cartographic.jpg b/Open-ILS/web/opac/images/tor/cartographic.jpg
new file mode 100644 (file)
index 0000000..5bbeacc
Binary files /dev/null and b/Open-ILS/web/opac/images/tor/cartographic.jpg differ
diff --git a/Open-ILS/web/opac/images/tor/mixed material.jpg b/Open-ILS/web/opac/images/tor/mixed material.jpg
new file mode 100644 (file)
index 0000000..bac8c57
Binary files /dev/null and b/Open-ILS/web/opac/images/tor/mixed material.jpg differ
diff --git a/Open-ILS/web/opac/images/tor/moving image.jpg b/Open-ILS/web/opac/images/tor/moving image.jpg
new file mode 100644 (file)
index 0000000..a339a24
Binary files /dev/null and b/Open-ILS/web/opac/images/tor/moving image.jpg differ
diff --git a/Open-ILS/web/opac/images/tor/notated music.jpg b/Open-ILS/web/opac/images/tor/notated music.jpg
new file mode 100644 (file)
index 0000000..4110c68
Binary files /dev/null and b/Open-ILS/web/opac/images/tor/notated music.jpg differ
diff --git a/Open-ILS/web/opac/images/tor/software, multimedia.jpg b/Open-ILS/web/opac/images/tor/software, multimedia.jpg
new file mode 100644 (file)
index 0000000..7e34ec6
Binary files /dev/null and b/Open-ILS/web/opac/images/tor/software, multimedia.jpg differ
diff --git a/Open-ILS/web/opac/images/tor/sound recording-musical.jpg b/Open-ILS/web/opac/images/tor/sound recording-musical.jpg
new file mode 100644 (file)
index 0000000..fd2232c
Binary files /dev/null and b/Open-ILS/web/opac/images/tor/sound recording-musical.jpg differ
diff --git a/Open-ILS/web/opac/images/tor/sound recording-nonmusical.jpg b/Open-ILS/web/opac/images/tor/sound recording-nonmusical.jpg
new file mode 100644 (file)
index 0000000..fd2232c
Binary files /dev/null and b/Open-ILS/web/opac/images/tor/sound recording-nonmusical.jpg differ
diff --git a/Open-ILS/web/opac/images/tor/sound recording.jpg b/Open-ILS/web/opac/images/tor/sound recording.jpg
new file mode 100644 (file)
index 0000000..fd2232c
Binary files /dev/null and b/Open-ILS/web/opac/images/tor/sound recording.jpg differ
diff --git a/Open-ILS/web/opac/images/tor/still images.jpg b/Open-ILS/web/opac/images/tor/still images.jpg
new file mode 100644 (file)
index 0000000..77f6171
Binary files /dev/null and b/Open-ILS/web/opac/images/tor/still images.jpg differ
diff --git a/Open-ILS/web/opac/images/tor/three dimensional object.jpg b/Open-ILS/web/opac/images/tor/three dimensional object.jpg
new file mode 100644 (file)
index 0000000..33a02c8
Binary files /dev/null and b/Open-ILS/web/opac/images/tor/three dimensional object.jpg differ
diff --git a/Open-ILS/web/opac/locale/en-US/lang.dtd b/Open-ILS/web/opac/locale/en-US/lang.dtd
new file mode 100644 (file)
index 0000000..8f7c5f4
--- /dev/null
@@ -0,0 +1,26 @@
+<!ENTITY nbsp "  ">
+
+<!-- Navigations links -->
+<!ENTITY navigate.home "Home">
+<!ENTITY navigate.home.title "Go to the Home page">
+<!ENTITY navigate.advanced "Advanced Search">
+<!ENTITY navigate.advanced.title "Go to the Advanced Search Page">
+<!ENTITY navigate.myopac "My OPAC">
+<!ENTITY navigate.myopac.title "Go to My OPAC">
+<!ENTITY navigate.login "Log in for personalized features">
+<!ENTITY navigate.login.title "Log in">
+<!ENTITY navigate.logout "Log out">
+<!ENTITY navigate.logout.title "Log out">
+
+<!-- Informational items -->
+<!ENTITY navigate.loggedinas "You are logged in as ">
+<!ENTITY navigate.loggedinas.title "Logged in as...">
+<!ENTITY navigate.titleGroupResults "Title Group Results">
+<!ENTITY navigate.titleResults "Title Results">
+
+
+<!-- Sidebar Header Labels -->
+<!ENTITY sidebar.relevantSubjects.headerLabel "Relevant Subjects">
+<!ENTITY sidebar.relevantAuthors.headerLabel "Relevant Authors">
+<!ENTITY sidebar.relevantSeries.headerLabel "Relevant Series">
+