[open-ils-commits] [GIT] Evergreen ILS branch rel_2_3 updated. 38227e733c4765b3dfdf77cb183851d7fca04a2e

Evergreen Git git at git.evergreen-ils.org
Mon Mar 4 14:51:20 EST 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, rel_2_3 has been updated
       via  38227e733c4765b3dfdf77cb183851d7fca04a2e (commit)
       via  b2abed9d5be75ab5c50e76f22ac379c5aef71919 (commit)
       via  c0b97feeca7d81e901ec801b649f4bdafc8459d5 (commit)
       via  5623ee46d455d6c2f0fd86d7bfc21cfa14154443 (commit)
       via  c1e101f3ea503aafc9b644cf732de705301af2d9 (commit)
       via  b33e783ed76fbb15e96385e9ec4ab606b443b410 (commit)
       via  e2bf0d302dcf53d50ed99715b5d6bce53d7512b8 (commit)
       via  e3a51440a154089dd3e1d702aa22603cd187ead1 (commit)
       via  b3112a156b57a0ded171a30d257d1fc479e33e31 (commit)
       via  5d5791f0b21a8d6fdee057e65a8749748f9afad9 (commit)
       via  abbd9181ac45f3461f71cfe9d2896e3d24693804 (commit)
       via  70f7c8a9671a9c62552aac4ee216cac24b545ed4 (commit)
       via  f8be2b0a1d71ee8b7d565eb7b838bd58e87a3569 (commit)
      from  accd12854102132b2a9b6e03c53512d0fbdd190d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 38227e733c4765b3dfdf77cb183851d7fca04a2e
Author: Ben Shum <bshum at biblio.org>
Date:   Wed Feb 27 22:37:31 2013 -0500

    LP#1086458: move up event listeners in place_hold.js
    
    The preceding two functions need the event listeners to be defined before
    use. Move up to prevent errors.
    
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>

diff --git a/Open-ILS/xul/staff_client/server/patron/place_hold.js b/Open-ILS/xul/staff_client/server/patron/place_hold.js
index 62049e7..f0424d2 100644
--- a/Open-ILS/xul/staff_client/server/patron/place_hold.js
+++ b/Open-ILS/xul/staff_client/server/patron/place_hold.js
@@ -17,10 +17,11 @@ function my_init() {
 
         var copy_ids = xul_param('copy_ids');
 
+        window.place_hold_event_listeners = new EventListenerList();
+
         populate_hold_usr_textbox();
         populate_pickup_lib_menu();
 
-        window.place_hold_event_listeners = new EventListenerList();
         window.place_hold_event_listeners.add($('request_btn'), 
             'command',
             function(ev) {

commit b2abed9d5be75ab5c50e76f22ac379c5aef71919
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Wed Feb 20 15:00:55 2013 -0500

    LP#1086458: fix typo
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/server/patron/info_group.js b/Open-ILS/xul/staff_client/server/patron/info_group.js
index bf30c84..d27db59 100644
--- a/Open-ILS/xul/staff_client/server/patron/info_group.js
+++ b/Open-ILS/xul/staff_client/server/patron/info_group.js
@@ -31,8 +31,8 @@ function my_init() {
 
 function my_cleanup() {
     try {
-        list.cleanup();
-        list.clear();
+        g.list.cleanup();
+        g.list.clear();
     } catch(E) {
         var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/info_group.xul', E]);
         try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }

commit c0b97feeca7d81e901ec801b649f4bdafc8459d5
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Wed Jan 30 11:38:33 2013 -0500

    LP#1086458: add destructor to caption binding
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml b/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml
index e823f13..c7881b5 100644
--- a/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml
+++ b/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml
@@ -556,6 +556,12 @@
 					n.setAttribute('src','chrome://open_ils_staff_client/skin/media/images/opentriangle.gif');
 				]]>
 			</constructor>
+			<destructor>
+				<![CDATA[
+					var n = document.getAnonymousNodes(this)[0];
+					n.onclick = null;
+				]]>
+			</destructor>
 		</implementation>
 	</binding>
 

commit 5623ee46d455d6c2f0fd86d7bfc21cfa14154443
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Wed Jan 30 11:24:21 2013 -0500

    LP#1086458: add destructor to messagecatalog
    
    Based on patch by Jason Etheridge.
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml b/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml
index 35f179e..e823f13 100644
--- a/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml
+++ b/Open-ILS/xul/staff_client/chrome/content/main/bindings.xml
@@ -147,6 +147,18 @@
 				]]>
 			</constructor>
 
+			<destructor>                                                                                              
+				<![CDATA[                                                                                         
+				try {                                                                                                            
+					delete this._props;                                                                                      
+					delete this.sprintf;                                                                                     
+				} catch(E) {                                                                                                     
+					alert('Error destroying messagecatalog in bindings.xml: ' + E);                                             
+					throw(E);                                                                                                    
+				}                                                                                                                
+				]]>                                                                                               
+			</destructor>  
+
 			<property name="src">
 				<getter>
 					<![CDATA[

commit c1e101f3ea503aafc9b644cf732de705301af2d9
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Wed Jan 30 10:59:10 2013 -0500

    LP#1086458: clean up event listener functions
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/chrome/content/OpenILS/event_util.js b/Open-ILS/xul/staff_client/chrome/content/OpenILS/event_util.js
index 39934b4..6e7d09d 100644
--- a/Open-ILS/xul/staff_client/chrome/content/OpenILS/event_util.js
+++ b/Open-ILS/xul/staff_client/chrome/content/OpenILS/event_util.js
@@ -21,13 +21,16 @@ EventListenerList.prototype = {
     'removeAll' : function() {
         try {
             if (typeof this._listeners != 'undefined') {
-                for (var i = 0; i < this._listeners.length; i++) {
+                for (var i = this._listeners.length - 1; i >= 0; i--) {
                     this._listeners[i].node.removeEventListener(
                         this._listeners[i].type,
                         this._listeners[i].listener,
                         this._listeners[i].useCapture
                     );
+                    this._listeners[i].listener = null;
+                    delete this._listeners[i];
                 }
+                this._listeners = [];
             }
         } catch(E) {
             alert(location.href + ' Error in unloadEventListeners(): ' + E);

commit b33e783ed76fbb15e96385e9ec4ab606b443b410
Author: Jason Etheridge <jason at esilibrary.com>
Date:   Thu Jan 24 17:30:26 2013 -0500

    move EventListenerList out of global_util.js
    
    So that we can more easily pull it into main.xul (which we also do here)
    
    Signed-off-by: Jason Etheridge <jason at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/Makefile.am b/Open-ILS/xul/staff_client/Makefile.am
index 9ecac6d..46ad9cc 100644
--- a/Open-ILS/xul/staff_client/Makefile.am
+++ b/Open-ILS/xul/staff_client/Makefile.am
@@ -101,6 +101,7 @@ build_dir:
 	@cp build/chrome/content/main/bindings.xml build/server/main/bindings.xml
 	@cp build/chrome/content/OpenILS/data.js build/server/OpenILS/data.js
 	@cp build/chrome/content/OpenILS/global_util.js build/server/OpenILS/global_util.js
+	@cp build/chrome/content/OpenILS/event_util.js build/server/OpenILS/event_util.js
 	@if [ -d branding ]; then cp -fR branding/* build/; fi
 	@external/prune_dirs.sh build/
 
diff --git a/Open-ILS/xul/staff_client/chrome/content/OpenILS/event_util.js b/Open-ILS/xul/staff_client/chrome/content/OpenILS/event_util.js
new file mode 100644
index 0000000..39934b4
--- /dev/null
+++ b/Open-ILS/xul/staff_client/chrome/content/OpenILS/event_util.js
@@ -0,0 +1,37 @@
+function EventListenerList() {
+    this._listeners = [];
+    return this;
+}
+
+EventListenerList.prototype = {
+    'add' : function(node, type, listener, useCapture) {
+        try {
+            node.addEventListener(type,listener,useCapture);
+            this._listeners.push({
+                'node' : node,
+                'type' : type,
+                'listener' : listener,
+                'useCapture' : useCapture
+            });
+        } catch(E) {
+            alert(location.href + ' Error adding event listener ' + type + ': ' + E);
+        }
+    },
+
+    'removeAll' : function() {
+        try {
+            if (typeof this._listeners != 'undefined') {
+                for (var i = 0; i < this._listeners.length; i++) {
+                    this._listeners[i].node.removeEventListener(
+                        this._listeners[i].type,
+                        this._listeners[i].listener,
+                        this._listeners[i].useCapture
+                    );
+                }
+            }
+        } catch(E) {
+            alert(location.href + ' Error in unloadEventListeners(): ' + E);
+        }
+    }
+}
+
diff --git a/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js b/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js
index 3f58aa6..b1ffecc 100644
--- a/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js
+++ b/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js
@@ -2,43 +2,6 @@
         xulG = window.arguments[0];
     }
 
-    function EventListenerList() {
-        this._listeners = [];
-        return this;
-    }
-
-    EventListenerList.prototype = {
-        'add' : function(node, type, listener, useCapture) {
-            try {
-                node.addEventListener(type,listener,useCapture);
-                this._listeners.push({
-                    'node' : node,
-                    'type' : type,
-                    'listener' : listener,
-                    'useCapture' : useCapture
-                });
-            } catch(E) {
-                alert(location.href + ' Error adding event listener ' + type + ': ' + E);
-            }
-        },
-
-        'removeAll' : function() {
-            try {
-                if (typeof this._listeners != 'undefined') {
-                    for (var i = 0; i < this._listeners.length; i++) {
-                        this._listeners[i].node.removeEventListener(
-                            this._listeners[i].type,
-                            this._listeners[i].listener,
-                            this._listeners[i].useCapture
-                        );
-                    }
-                }
-            } catch(E) {
-                alert(location.href + ' Error in unloadEventListeners(): ' + E);
-            }
-        }
-    }
-
     function $(id) { return document.getElementById(id); }
 
     function oils_unsaved_data_V() {
diff --git a/Open-ILS/xul/staff_client/chrome/content/OpenILS/util_overlay_chrome.xul b/Open-ILS/xul/staff_client/chrome/content/OpenILS/util_overlay_chrome.xul
index c3b9e47..0860a6d 100644
--- a/Open-ILS/xul/staff_client/chrome/content/OpenILS/util_overlay_chrome.xul
+++ b/Open-ILS/xul/staff_client/chrome/content/OpenILS/util_overlay_chrome.xul
@@ -63,6 +63,7 @@
         <script type='text/javascript' src='util/en-US/OrgTree.js' />
         <script type="text/javascript" src="util/org_utils.js" />   
         <script type="text/javascript" src="global_util.js" />   
+        <script type="text/javascript" src="event_util.js" />   
         <messagecatalog id="offlineStrings" src='chrome://open_ils_staff_client/locale/offline.properties'/>
         <messagecatalog id="authStrings" src='chrome://open_ils_staff_client/locale/auth.properties'/>
         <hbox id="debug_box" hidden="true" flex="1" style="border: red thin dashed">
diff --git a/Open-ILS/xul/staff_client/chrome/content/OpenILS/util_overlay_offline.xul b/Open-ILS/xul/staff_client/chrome/content/OpenILS/util_overlay_offline.xul
index 2b834db..a9dc1d8 100644
--- a/Open-ILS/xul/staff_client/chrome/content/OpenILS/util_overlay_offline.xul
+++ b/Open-ILS/xul/staff_client/chrome/content/OpenILS/util_overlay_offline.xul
@@ -60,6 +60,7 @@
         <script type="text/javascript" src="util/md5.js" />
         <script type="text/javascript" src="util/JSON_v1.js" />
         <script type="text/javascript" src="global_util.js" />   
+        <script type="text/javascript" src="event_util.js" />   
         <hbox id="debug_box" hidden="true" flex="1" style="border: red thin dashed">
             <label value="Debug:" />
             <textbox id="debug_tb" flex="1"/>
diff --git a/Open-ILS/xul/staff_client/chrome/content/main/main.xul b/Open-ILS/xul/staff_client/chrome/content/main/main.xul
index 1ba8226..3884d9c 100644
--- a/Open-ILS/xul/staff_client/chrome/content/main/main.xul
+++ b/Open-ILS/xul/staff_client/chrome/content/main/main.xul
@@ -45,6 +45,7 @@
         <script type="text/javascript" src="../OpenILS/util/OrgTree.js" />
         -->
         <script type="text/javascript" src="../OpenILS/util/org_utils.js" />   
+        <script type="text/javascript" src="../OpenILS/event_util.js" />   
     </scripts>
     <script>dump('Loaded main/main.xul\n');</script>
 
diff --git a/Open-ILS/xul/staff_client/chrome/content/util/shell.html b/Open-ILS/xul/staff_client/chrome/content/util/shell.html
index 32a7cc2..884c48e 100644
--- a/Open-ILS/xul/staff_client/chrome/content/util/shell.html
+++ b/Open-ILS/xul/staff_client/chrome/content/util/shell.html
@@ -8,6 +8,7 @@
 <script type="text/javascript" src="/xul/server/main/JSAN.js" />
 <script type="text/javascript" src="/xul/server/main/constants.js" />
 <script type="text/javascript" src="/xul/server/OpenILS/global_util.js" />
+<script type="text/javascript" src="/xul/server/OpenILS/event_util.js" />
 <script type="text/javascript" src="/xul/server/OpenILS/data.js" />
 <script type="text/javascript" src="/xul/server/util/network.js" />
 <script type="text/javascript" src="/xul/server/util/error.js" />
diff --git a/Open-ILS/xul/staff_client/server/OpenILS/util_overlay.xul b/Open-ILS/xul/staff_client/server/OpenILS/util_overlay.xul
index b4b81ac..dec055d 100644
--- a/Open-ILS/xul/staff_client/server/OpenILS/util_overlay.xul
+++ b/Open-ILS/xul/staff_client/server/OpenILS/util_overlay.xul
@@ -73,6 +73,7 @@
         <script type='text/javascript' src='/opac/common/js/<!--#echo var="locale"-->/OrgTree.js' />
         <script type="text/javascript" src="/opac/common/js/org_utils.js" />   
         <script type="text/javascript" src="global_util.js" />   
+        <script type="text/javascript" src="event_util.js" />   
         <menupopup id="clipboard">
             <menuitem label="&common.textbox.cut;" oncommand="util.clipboard.cut()" />
             <menuitem label="&common.textbox.copy;" oncommand="util.clipboard.copy()" />
diff --git a/Open-ILS/xul/staff_client/server/admin/printer_settings.xul b/Open-ILS/xul/staff_client/server/admin/printer_settings.xul
index e8f61ae..6df759b 100644
--- a/Open-ILS/xul/staff_client/server/admin/printer_settings.xul
+++ b/Open-ILS/xul/staff_client/server/admin/printer_settings.xul
@@ -23,6 +23,7 @@
     <script type="text/javascript" src="/opac/common/js/org_utils.js"></script>
 
     <script type="text/javascript" src="/xul/server/OpenILS/global_util.js"></script>
+    <script type="text/javascript" src="/xul/server/OpenILS/event_util.js"></script>
     <script type="text/javascript" src="/xul/server/main/constants.js"></script>
     <script type="text/javascript" src="/xul/server/main/JSAN.js"></script>
     <script type="text/javascript" src="printer_settings.js"></script>
diff --git a/Open-ILS/xul/staff_client/server/admin/upload_xacts.xhtml b/Open-ILS/xul/staff_client/server/admin/upload_xacts.xhtml
index eae0bbe..5f851c6 100644
--- a/Open-ILS/xul/staff_client/server/admin/upload_xacts.xhtml
+++ b/Open-ILS/xul/staff_client/server/admin/upload_xacts.xhtml
@@ -15,6 +15,7 @@
     <script type="text/javascript" src="/xul/server/main/JSAN.js"></script>
     <script type="text/javascript" src="/xul/server/main/constants.js" />
     <script type="text/javascript" src="/xul/server/OpenILS/global_util.js" />
+    <script type="text/javascript" src="/xul/server/OpenILS/event_util.js" />
 
     <script type="text/javascript" src="/opac/common/js/utils.js" />
     <script type="text/javascript" src="/opac/common/js/CGI.js" />
diff --git a/Open-ILS/xul/staff_client/server/index.xhtml b/Open-ILS/xul/staff_client/server/index.xhtml
index b0ddccd..8fb7f1d 100644
--- a/Open-ILS/xul/staff_client/server/index.xhtml
+++ b/Open-ILS/xul/staff_client/server/index.xhtml
@@ -74,6 +74,8 @@
 </script>
   <script type="text/javascript" src="OpenILS/global_util.js">
 </script>
+  <script type="text/javascript" src="OpenILS/event_util.js">
+</script>
   <script type="text/javascript" src="main/JSAN.js">
 </script>
   <script type="text/javascript">

commit e2bf0d302dcf53d50ed99715b5d6bce53d7512b8
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Thu Jan 24 15:25:47 2013 -0500

    LP#1086458: remove references to windows during cleanup
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/server/patron/display.js b/Open-ILS/xul/staff_client/server/patron/display.js
index 9237bdc..28522af 100644
--- a/Open-ILS/xul/staff_client/server/patron/display.js
+++ b/Open-ILS/xul/staff_client/server/patron/display.js
@@ -677,6 +677,12 @@ patron.display.prototype = {
 
     'cleanup' : function( params ) {
         var obj = this;
+        delete obj.search_result;
+        delete obj.search_window;
+        delete obj.patron;
+        delete obj.items_window;
+        delete obj.summary_window;
+        delete obj.checkout_window;
         obj.controller.cleanup();
         obj.event_listeners.removeAll();
     },

commit e3a51440a154089dd3e1d702aa22603cd187ead1
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Thu Jan 24 15:16:52 2013 -0500

    LP#1086458: clear util.list lists and trees during cleanup
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/server/patron/bill2.js b/Open-ILS/xul/staff_client/server/patron/bill2.js
index 040c559..6adf3f2 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill2.js
+++ b/Open-ILS/xul/staff_client/server/patron/bill2.js
@@ -68,6 +68,7 @@ function my_cleanup() {
     try {
         window.bill_event_listeners.removeAll();
         g.bill_list.cleanup();
+        g.bill_list.clear();
     } catch(E) {
         var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/bill2.xul', E]);
         try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
diff --git a/Open-ILS/xul/staff_client/server/patron/bill_details.js b/Open-ILS/xul/staff_client/server/patron/bill_details.js
index fbb519f..cb5f3c2 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill_details.js
+++ b/Open-ILS/xul/staff_client/server/patron/bill_details.js
@@ -252,7 +252,9 @@ function my_init() {
 function my_cleanup() {
     try {
         g.bill_list.cleanup();
+        g.bill_list.clear();
         g.payment_list.cleanup();
+        g.payment_list.clear();
         window.bill_details_event_listeners.removeAll();
     } catch(E) {
         try { g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.bill_details.my_cleanup.error'),E); } catch(F) { alert(E); }
diff --git a/Open-ILS/xul/staff_client/server/patron/bill_history.js b/Open-ILS/xul/staff_client/server/patron/bill_history.js
index e1365cd..d897f6f 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill_history.js
+++ b/Open-ILS/xul/staff_client/server/patron/bill_history.js
@@ -288,7 +288,9 @@ function my_init() {
 function my_cleanup() {
     try {
         g.bill_list.cleanup();
+        g.bill_list.clear();
         g.payments_list.cleanup();
+        g.payments_list.clear();
         window.bill_history_event_listeners.removeAll();
     } catch(E) {
         var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/bill_history.xul', E]);
diff --git a/Open-ILS/xul/staff_client/server/patron/hold_details.js b/Open-ILS/xul/staff_client/server/patron/hold_details.js
index f583094..edf4359 100644
--- a/Open-ILS/xul/staff_client/server/patron/hold_details.js
+++ b/Open-ILS/xul/staff_client/server/patron/hold_details.js
@@ -32,6 +32,7 @@ function my_init() {
 function my_cleanup() {
     try {
         g.list.cleanup();
+        g.list.clear();
     } catch(E) {
         try { g.error.standard_unexpected_error_alert('/xul/server/patron/hold_notices.xul',E); } catch(E) { alert('FIXME: ' + js2JSON(E)); }
     }
diff --git a/Open-ILS/xul/staff_client/server/patron/holds.js b/Open-ILS/xul/staff_client/server/patron/holds.js
index eaa29c4..c90e28f 100644
--- a/Open-ILS/xul/staff_client/server/patron/holds.js
+++ b/Open-ILS/xul/staff_client/server/patron/holds.js
@@ -1637,6 +1637,7 @@ patron.holds.prototype = {
         var obj = this;
         obj.controller.cleanup();
         obj.list.cleanup();
+        obj.list.clear();
         obj.event_listeners.removeAll();
     },
 
diff --git a/Open-ILS/xul/staff_client/server/patron/info_group.js b/Open-ILS/xul/staff_client/server/patron/info_group.js
index a9407ce..bf30c84 100644
--- a/Open-ILS/xul/staff_client/server/patron/info_group.js
+++ b/Open-ILS/xul/staff_client/server/patron/info_group.js
@@ -32,6 +32,7 @@ function my_init() {
 function my_cleanup() {
     try {
         list.cleanup();
+        list.clear();
     } catch(E) {
         var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/info_group.xul', E]);
         try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
diff --git a/Open-ILS/xul/staff_client/server/patron/items.js b/Open-ILS/xul/staff_client/server/patron/items.js
index 7d2b65a..d129339 100644
--- a/Open-ILS/xul/staff_client/server/patron/items.js
+++ b/Open-ILS/xul/staff_client/server/patron/items.js
@@ -228,7 +228,9 @@ patron.items.prototype = {
     'cleanup' : function() {
         var obj = this;
         obj.list.cleanup();
+        obj.list.clear();
         obj.list2.cleanup();
+        obj.list2.clear();
     },
 
     'show_noncats' : function() {
diff --git a/Open-ILS/xul/staff_client/server/patron/search_result.js b/Open-ILS/xul/staff_client/server/patron/search_result.js
index 8a77a71..49c4522 100644
--- a/Open-ILS/xul/staff_client/server/patron/search_result.js
+++ b/Open-ILS/xul/staff_client/server/patron/search_result.js
@@ -190,6 +190,7 @@ patron.search_result.prototype = {
         var obj = this;
         obj.controller.cleanup();
         obj.list.cleanup();
+        obj.list.clear();
     },
 
     'search' : function(query) {
diff --git a/Open-ILS/xul/staff_client/server/patron/staged.js b/Open-ILS/xul/staff_client/server/patron/staged.js
index 246a57d..8909555 100644
--- a/Open-ILS/xul/staff_client/server/patron/staged.js
+++ b/Open-ILS/xul/staff_client/server/patron/staged.js
@@ -53,6 +53,7 @@ function staged_init() {
 function staged_cleanup() {
     try {
         list.cleanup();
+        list.clear();
         window.staged_event_listeners.removeAll();
     } catch(E) {
         var err_prefix = 'staged.js -> staged_cleanup() : ';
diff --git a/Open-ILS/xul/staff_client/server/patron/standing_penalties.js b/Open-ILS/xul/staff_client/server/patron/standing_penalties.js
index 7b9f714..7a1786f 100644
--- a/Open-ILS/xul/staff_client/server/patron/standing_penalties.js
+++ b/Open-ILS/xul/staff_client/server/patron/standing_penalties.js
@@ -48,7 +48,9 @@ function penalty_cleanup() {
     try {
         window.standing_penalties_event_listeners.removeAll();
         list.cleanup();
+        list.clear();
         archived_list.cleanup();
+        archived_list.clear();
     } catch(E) {
         var err_prefix = 'standing_penalties.js -> penalty_cleanup() : ';
         if (error) error.standard_unexpected_error_alert(err_prefix,E); else alert(err_prefix + E);
diff --git a/Open-ILS/xul/staff_client/server/patron/summary.js b/Open-ILS/xul/staff_client/server/patron/summary.js
index 6b73ff9..e560b64 100644
--- a/Open-ILS/xul/staff_client/server/patron/summary.js
+++ b/Open-ILS/xul/staff_client/server/patron/summary.js
@@ -933,8 +933,14 @@ patron.summary.prototype = {
 
     'cleanup' : function() {
         var obj = this;
-        if (typeof obj.group_list != 'undefined') obj.group_list.cleanup();
-        if (typeof obj.stat_cat_list != 'undefined') obj.stat_cat_list.cleanup();
+        if (typeof obj.group_list != 'undefined') {
+            obj.group_list.cleanup();
+            obj.group_list.clear();
+        }
+        if (typeof obj.stat_cat_list != 'undefined') {
+            obj.stat_cat_list.cleanup();
+            obj.stat_cat_list.clear();
+        }
         obj.controller.cleanup();
         obj.event_listeners.removeAll();
     },

commit b3112a156b57a0ded171a30d257d1fc479e33e31
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Thu Jan 24 13:07:05 2013 -0500

    LP#1086458: add missing cleanup call
    
    Thanks to Jason Etheridge for the catch.
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/server/circ/checkout.js b/Open-ILS/xul/staff_client/server/circ/checkout.js
index 69c3119..e8a7169 100644
--- a/Open-ILS/xul/staff_client/server/circ/checkout.js
+++ b/Open-ILS/xul/staff_client/server/circ/checkout.js
@@ -272,6 +272,7 @@ circ.checkout.prototype = {
 
     'cleanup' : function() {
         var obj = this;
+        obj.list.cleanup();
         obj.controller.cleanup();
         obj.event_listeners.removeAll();
     },

commit 5d5791f0b21a8d6fdee057e65a8749748f9afad9
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Sat Jan 19 00:46:32 2013 -0500

    LP#1086458: clean up after event listeners in circ/patron interface
    
    Upon window unload, now removes event listeners, both ones explicitly
    created by the page JavsScript as well as ones created by
    util.list, util.controller, and persist_helper().
    
    The same approach of defining cleanup fnctions used by unload
    events can be applied to the rest of the staff client, but
    this patch focuses on circulation first.
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/server/circ/checkout.js b/Open-ILS/xul/staff_client/server/circ/checkout.js
index 08455c3..69c3119 100644
--- a/Open-ILS/xul/staff_client/server/circ/checkout.js
+++ b/Open-ILS/xul/staff_client/server/circ/checkout.js
@@ -16,6 +16,7 @@ circ.checkout.prototype = {
 
         var obj = this;
 
+        obj.event_listeners = new EventListenerList();
         obj.patron_id = params.patron_id;
 
         obj.auto_override_events = [];
@@ -87,7 +88,7 @@ circ.checkout.prototype = {
                                 e.appendChild( ml );
                                 ml.setAttribute('id','checkout_menulist');
                                 ml.setAttribute('accesskey','');
-                                ml.addEventListener(
+                                obj.event_listeners.add(ml,
                                     'command',
                                     function(ev) {
                                         var tb = obj.controller.view.checkout_barcode_entry_textbox;
@@ -269,6 +270,12 @@ circ.checkout.prototype = {
 
     },
 
+    'cleanup' : function() {
+        var obj = this;
+        obj.controller.cleanup();
+        obj.event_listeners.removeAll();
+    },
+
     'check_disable' : function() {
         var obj = this;
         try {
diff --git a/Open-ILS/xul/staff_client/server/circ/checkout.xul b/Open-ILS/xul/staff_client/server/circ/checkout.xul
index 75c8a55..c1ba2ee 100644
--- a/Open-ILS/xul/staff_client/server/circ/checkout.xul
+++ b/Open-ILS/xul/staff_client/server/circ/checkout.xul
@@ -21,6 +21,7 @@
 
 <window id="checkout_win" 
     onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
@@ -59,6 +60,18 @@
             }
         }
 
+        function my_cleanup() {
+            try {
+                g.checkout.cleanup();
+            } catch(E) {
+                try {
+                    g.error.standard_unexpected_error_alert('circ/checkout.xul',E);
+                } catch(F) {
+                    dump('FIXME: circ/checkout.xul -> ' + E + ' -> ' + F + '\n');
+                }
+            }
+        }
+
         function default_focus() {
             try {
                 var x = document.getElementById('checkout_barcode_entry_textbox');
diff --git a/Open-ILS/xul/staff_client/server/locale/en-US/patron.properties b/Open-ILS/xul/staff_client/server/locale/en-US/patron.properties
index 55b750c..fd9faf5 100644
--- a/Open-ILS/xul/staff_client/server/locale/en-US/patron.properties
+++ b/Open-ILS/xul/staff_client/server/locale/en-US/patron.properties
@@ -14,6 +14,7 @@ staff.patron.bill_interface.payment_pending.column_header=Payment Pending
 staff.patron.bill_cc_info.need_cc_number=You must provide a credit card number
 staff.patron.bill_cc_info.need_approval_code=You must provide an approval code or an imprint slip number
 staff.patron.bill_details.my_init.error=bill_details.xul, my_init:
+staff.patron.bill_details.my_cleanup.error=bill_details.xul, my_cleanup:
 staff.patron.bill_details.handle_edit_bill_note.note_dialog.title=Replacement Note
 staff.patron.bill_details.handle_edit_bill_note.note_dialog.prompt=Enter new note:
 staff.patron.bill_details.handle_edit_bill_note.failure=Note for selected bills not likely updated.
diff --git a/Open-ILS/xul/staff_client/server/patron/barcode_entry.xul b/Open-ILS/xul/staff_client/server/patron/barcode_entry.xul
index bd8f077..d2e2405 100644
--- a/Open-ILS/xul/staff_client/server/patron/barcode_entry.xul
+++ b/Open-ILS/xul/staff_client/server/patron/barcode_entry.xul
@@ -19,6 +19,7 @@
 
 <window id="patron_barcode_entry_win" 
     onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
@@ -42,7 +43,8 @@
                 JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
 
                 var tb = document.getElementById('barcode_tb');
-                tb.addEventListener(
+                window.barcode_entry_event_listeners = new EventListenerList();
+                window.barcode_entry_event_listeners.add(tb, 
                     'keypress',
                     function(ev) {
                         if (ev.keyCode == 13 || ev.keyCode == 77) {
@@ -77,6 +79,16 @@
             }
         }
 
+        function my_cleanup() {
+            try {
+                window.barcode_entry_event_listeners.removeAll();
+            } catch(E) {
+                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/barcode_entry.xul', E]);
+                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+                alert(err_msg);
+            }
+        }
+
         function submit() {
             var tb;
             try {
diff --git a/Open-ILS/xul/staff_client/server/patron/bill2.js b/Open-ILS/xul/staff_client/server/patron/bill2.js
index 6c0b7de..040c559 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill2.js
+++ b/Open-ILS/xul/staff_client/server/patron/bill2.js
@@ -14,6 +14,7 @@ function my_init() {
         g.data.voided_billings = []; g.data.stash('voided_billings');
 
         g.error.sdump('D_TRACE','my_init() for bill2.xul');
+        window.bill_event_listeners = new EventListenerList();
 
         document.title = $("patronStrings").getString('staff.patron.bill_history.my_init.current_bills');
 
@@ -63,45 +64,56 @@ function my_init() {
     }
 }
 
+function my_cleanup() {
+    try {
+        window.bill_event_listeners.removeAll();
+        g.bill_list.cleanup();
+    } catch(E) {
+        var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/bill2.xul', E]);
+        try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+        alert(err_msg);
+    }
+}
+
 function event_listeners() {
     try {
-        $('details').addEventListener(
+        window.bill_event_listeners.add($('details'), 
             'command',
             handle_details,
             false
         );
 
-        $('add').addEventListener(
+        window.bill_event_listeners.add($('add'), 
             'command',
             handle_add,
             false
         );
 
-        $('voidall').addEventListener(
+        window.bill_event_listeners.add($('voidall'), 
             'command',
             handle_void_all,
             false
         );
 
-        $('refund').addEventListener(
+        window.bill_event_listeners.add($('refund'), 
             'command',
             handle_refund,
             false
         );
 
-        $('opac').addEventListener(
+        window.bill_event_listeners.add($('opac'), 
             'command',
             handle_opac,
             false
         );
 
-        $('copy_details').addEventListener(
+        window.bill_event_listeners.add($('copy_details'), 
             'command',
             handle_copy_details,
             false
         );
 
-        $('payment').addEventListener(
+        window.bill_event_listeners.add($('payment'), 
             'change',
             function(ev) {
                 if ($('payment_type').value == 'credit_payment') {
@@ -120,13 +132,13 @@ function event_listeners() {
             false
         );
 
-        $('payment').addEventListener(
+        window.bill_event_listeners.add($('payment'), 
             'focus',
             function(ev) { ev.target.select(); },
             false
         );
 
-        $('payment').addEventListener(
+        window.bill_event_listeners.add($('payment'), 
             'keypress',
             function(ev) {
                 if (! (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) ) { return; }
@@ -136,7 +148,7 @@ function event_listeners() {
             false
         );
 
-        $('bill_patron_btn').addEventListener(
+        window.bill_event_listeners.add($('bill_patron_btn'), 
             'command',
             function() {
                 JSAN.use('util.window'); var win = new util.window();
@@ -151,7 +163,7 @@ function event_listeners() {
             false
         );
 
-        $('bill_history_btn').addEventListener(
+        window.bill_event_listeners.add($('bill_history_btn'), 
             'command',
             function() {
                 xulG.display_window.g.patron.right_deck.reset_iframe( 
@@ -168,7 +180,7 @@ function event_listeners() {
             false
         );
 
-        $('convert_change_to_credit').addEventListener(
+        window.bill_event_listeners.add($('convert_change_to_credit'), 
             'command',
             function(ev) {
                 if (ev.target.checked) {
@@ -180,7 +192,7 @@ function event_listeners() {
             false
         );
 
-        $('apply_payment_btn').addEventListener(
+        window.bill_event_listeners.add($('apply_payment_btn'), 
             'command',
             function(ev) {
                 try {
diff --git a/Open-ILS/xul/staff_client/server/patron/bill2.xul b/Open-ILS/xul/staff_client/server/patron/bill2.xul
index 51167a5..32f0e0b 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill2.xul
+++ b/Open-ILS/xul/staff_client/server/patron/bill2.xul
@@ -22,6 +22,7 @@
 
 <window id="bill_interface_win" width="700" height="550" oils_persist="sizemode width height" active="true"
     onload="try{ font_helper(); persist_helper(); my_init(); } catch(E) { alert(E); }"
+    onunload="try{ my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/bill_cc_info.xul b/Open-ILS/xul/staff_client/server/patron/bill_cc_info.xul
index 3633745..8cb4804 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill_cc_info.xul
+++ b/Open-ILS/xul/staff_client/server/patron/bill_cc_info.xul
@@ -21,6 +21,7 @@
 <window id="patron_bill" title="&staff.patron.bill_cc_info.title;"
     orient="vertical" style="overflow: auto" oils_persist="height width sizemode"
     onload="try{info_init(); font_helper(); refresh_fields(); persist_helper(); }catch(E){alert(E);}"
+    onunload="try {  persist_helper_cleanup(); } catch(E) { alert(E) }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/bill_check_info.xul b/Open-ILS/xul/staff_client/server/patron/bill_check_info.xul
index 71738ec..373a74b 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill_check_info.xul
+++ b/Open-ILS/xul/staff_client/server/patron/bill_check_info.xul
@@ -21,6 +21,7 @@
 <window id="patron_bill" title="&staff.patron.bill_check_info.title;"
     orient="vertical" style="overflow: auto" oils_persist="height width sizemode"
     onload="try{info_init(); font_helper(); persist_helper(); }catch(E){alert(E);}"
+    onunload="try{ persist_helper_cleanup(); }catch(E){alert(E);}"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/bill_details.js b/Open-ILS/xul/staff_client/server/patron/bill_details.js
index 52c4e06..fbb519f 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill_details.js
+++ b/Open-ILS/xul/staff_client/server/patron/bill_details.js
@@ -215,6 +215,8 @@ function my_init() {
 
         g.mbts_id = xul_param('mbts_id');
 
+        window.bill_details_event_listeners = new EventListenerList();
+
         retrieve_patron();
 
         retrieve_mbts();
@@ -224,19 +226,19 @@ function my_init() {
         retrieve_mb();
         retrieve_mp();
 
-        $('void').addEventListener(
+        window.bill_details_event_listeners.add($('void'), 
             'command',
             handle_void,
             false
         );
 
-        $('edit_bill_note').addEventListener(
+        window.bill_details_event_listeners.add($('edit_bill_note'), 
             'command',
             handle_edit_bill_note,
             false
         );
 
-        $('edit_payment_note').addEventListener(
+        window.bill_details_event_listeners.add($('edit_payment_note'), 
             'command',
             handle_edit_payment_note,
             false
@@ -247,6 +249,16 @@ function my_init() {
     }
 }
 
+function my_cleanup() {
+    try {
+        g.bill_list.cleanup();
+        g.payment_list.cleanup();
+        window.bill_details_event_listeners.removeAll();
+    } catch(E) {
+        try { g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.bill_details.my_cleanup.error'),E); } catch(F) { alert(E); }
+    }
+}
+
 function handle_edit_bill_note() {
     try {
         var mb_list = util.functional.map_list(g.bill_list_selection, function(o){return g.mb_list[o].id();}); 
diff --git a/Open-ILS/xul/staff_client/server/patron/bill_details.xul b/Open-ILS/xul/staff_client/server/patron/bill_details.xul
index a16d4e7..2454d35 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill_details.xul
+++ b/Open-ILS/xul/staff_client/server/patron/bill_details.xul
@@ -22,6 +22,7 @@
 
 <window id="bill_details_win" width="700" height="550" oils_persist="width height sizemode"
     onload="try{ my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/bill_history.js b/Open-ILS/xul/staff_client/server/patron/bill_history.js
index 098a140..e1365cd 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill_history.js
+++ b/Open-ILS/xul/staff_client/server/patron/bill_history.js
@@ -237,6 +237,7 @@ function my_init() {
         g.funcs = []; g.bill_map = {}; g.payments_map = {};
 
         g.patron_id = xul_param('patron_id');
+        window.bill_history_event_listeners = new EventListenerList();
 
         init_lists();
 
@@ -244,31 +245,31 @@ function my_init() {
 
         retrieve_mbts_for_list();
 
-        $('details').addEventListener(
+        window.bill_history_event_listeners.add($('details'), 
             'command',
             gen_handle_details('bills'),
             false
         );
 
-        $('payments_details').addEventListener(
+        window.bill_history_event_listeners.add($('payments_details'), 
             'command',
             gen_handle_details('payments'),
             false
         );
 
-        $('copy_details').addEventListener(
+        window.bill_history_event_listeners.add($('copy_details'), 
             'command',
             gen_handle_copy_details('bills'),
             false
         );
 
-        $('copy_details_from_payments').addEventListener(
+        window.bill_history_event_listeners.add($('copy_details_from_payments'), 
             'command',
             gen_handle_copy_details('payments'),
             false
         );
 
-        $('add').addEventListener(
+        window.bill_history_event_listeners.add($('add'), 
             'command',
             handle_add,
             false
@@ -284,6 +285,19 @@ function my_init() {
     }
 }
 
+function my_cleanup() {
+    try {
+        g.bill_list.cleanup();
+        g.payments_list.cleanup();
+        window.bill_history_event_listeners.removeAll();
+    } catch(E) {
+        var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/bill_history.xul', E]);
+        try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+        alert(err_msg);
+    }
+}
+
+
 function handle_add() {
     if(g.bill_list_selection.length > 1)
         var msg = $("patronStrings").getFormattedString('staff.patron.bill_history.handle_add.message_plural', [g.bill_list_selection]);
diff --git a/Open-ILS/xul/staff_client/server/patron/bill_history.xul b/Open-ILS/xul/staff_client/server/patron/bill_history.xul
index 128ce1d..9671de1 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill_history.xul
+++ b/Open-ILS/xul/staff_client/server/patron/bill_history.xul
@@ -22,6 +22,7 @@
 
 <window id="bill_history_win" width="700" height="550" oils_persist="sizemode width height"
     onload="try{ my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/bill_wizard.js b/Open-ILS/xul/staff_client/server/patron/bill_wizard.js
index 1dc3147..25ef0a9 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill_wizard.js
+++ b/Open-ILS/xul/staff_client/server/patron/bill_wizard.js
@@ -116,7 +116,8 @@ function patron_bill_init() {
         );
         ml.setAttribute('id','billing_type');
         document.getElementById('menu_placeholder').appendChild(ml);
-        ml.addEventListener(
+        window.bill_wizard_event_listeners = new EventListenerList();
+        window.bill_wizard_event_listeners.add(ml, 
             'command',
             function() {
                 if ( g.OpenILS.data.hash.cbt[ ml.value ] ) {
@@ -155,6 +156,17 @@ function patron_bill_init() {
 
 }
 
+function patron_bill_cleanup() {
+    try {
+        window.bill_wizard_event_listeners.removeAll();
+    } catch(E) {
+        var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/bill_wizard.xul', E]);
+        try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+        alert(err_msg);
+    }
+
+}
+
 function patron_bill_finish() {
     try {
         var do_not_process_bill = xul_param('do_not_process_bill');
diff --git a/Open-ILS/xul/staff_client/server/patron/bill_wizard.xul b/Open-ILS/xul/staff_client/server/patron/bill_wizard.xul
index 126f021..44cb12a 100644
--- a/Open-ILS/xul/staff_client/server/patron/bill_wizard.xul
+++ b/Open-ILS/xul/staff_client/server/patron/bill_wizard.xul
@@ -22,6 +22,7 @@
 <window id="patron_bill" title="&staff.patron.bill_wizard.title;"
     orient="vertical" style="overflow: auto" oils_persist="width height sizemode"
     onload="try { patron_bill_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }" width="700" height="550"
+    onunload="try { patron_bill_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/display.js b/Open-ILS/xul/staff_client/server/patron/display.js
index 7e2a547..9237bdc 100644
--- a/Open-ILS/xul/staff_client/server/patron/display.js
+++ b/Open-ILS/xul/staff_client/server/patron/display.js
@@ -24,6 +24,7 @@ patron.display.prototype = {
 
         var obj = this;
 
+        obj.event_listeners = new EventListenerList();
         obj.barcode = params['barcode'];
         obj.id = params['id'];
 
@@ -600,22 +601,22 @@ patron.display.prototype = {
             }
         );
 
-        var x = document.getElementById("PatronNavBar_checkout");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_refresh");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_items");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_holds");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_other");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_edit");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_bills");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
-        var x = document.getElementById("PatronNavBar_messages");
-        x.addEventListener( 'focus', function(xx) { return function() { try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; } }(x), false);
+        var make_listener = function(xx) {
+            return function() { 
+                try { document.getElementById("PatronNavBarScrollbox").ensureElementIsVisible(xx); } catch(E) {}; 
+            }
+        };
+
+        
+        var need_focus_listeners = [
+            'PatronNavBar_checkout', 'PatronNavBar_refresh', 'PatronNavBar_items', 'PatronNavBar_holds',
+            'PatronNavBar_other', 'PatronNavBar_edit', 'PatronNavBar_bills', 'PatronNavBar_messages'
+        ];
+        for (var i = 0; i < need_focus_listeners.length; i++) {
+            var elementID = need_focus_listeners[i];
+            var x = document.getElementById(elementID);
+            obj.event_listeners.add(x, 'focus', make_listener(x), false);
+        }
 
         if (obj.barcode || obj.id) {
             if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') {
@@ -674,6 +675,12 @@ patron.display.prototype = {
         }
     },
 
+    'cleanup' : function( params ) {
+        var obj = this;
+        obj.controller.cleanup();
+        obj.event_listeners.removeAll();
+    },
+
     'reset_nav_styling' : function(btn,dont_hide_summary) {
         try {
             if (!dont_hide_summary) { dont_hide_summary = false; }
diff --git a/Open-ILS/xul/staff_client/server/patron/display.xul b/Open-ILS/xul/staff_client/server/patron/display.xul
index e0861db..65a1a74 100644
--- a/Open-ILS/xul/staff_client/server/patron/display.xul
+++ b/Open-ILS/xul/staff_client/server/patron/display.xul
@@ -21,6 +21,7 @@
 
 <window id="patron_display_win" 
     onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
@@ -62,6 +63,16 @@
             }
         }
 
+        function my_cleanup() {
+            try {
+                g.patron.cleanup();
+            } catch(E) {
+                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/display.xul', E]);
+                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+                alert(err_msg);
+            }
+        }
+
         function default_focus() {
             setTimeout(
                 function() {
diff --git a/Open-ILS/xul/staff_client/server/patron/display_horiz.xul b/Open-ILS/xul/staff_client/server/patron/display_horiz.xul
index 1c53834..52aa0b6 100644
--- a/Open-ILS/xul/staff_client/server/patron/display_horiz.xul
+++ b/Open-ILS/xul/staff_client/server/patron/display_horiz.xul
@@ -21,6 +21,7 @@
 
 <window id="patron_display_win" 
     onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
@@ -62,6 +63,16 @@
             }
         }
 
+        function my_cleanup() {
+            try {
+                g.patron.cleanup();
+            } catch(E) {
+                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/display.xul', E]);
+                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+                alert(err_msg);
+            }
+        }
+
         function default_focus() {
             setTimeout(
                 function() {
diff --git a/Open-ILS/xul/staff_client/server/patron/edit_standing_penalty.js b/Open-ILS/xul/staff_client/server/patron/edit_standing_penalty.js
index b2d60fd..0ae197b 100644
--- a/Open-ILS/xul/staff_client/server/patron/edit_standing_penalty.js
+++ b/Open-ILS/xul/staff_client/server/patron/edit_standing_penalty.js
@@ -48,7 +48,8 @@ function edit_penalty_init() {
         }
 
         /* set widget behavior */
-        document.getElementById('csp_menulist').addEventListener(
+        window.edit_standing_penalty_event_listeners = new EventListenerList();
+        window.edit_standing_penalty_event_listeners.add(document.getElementById('csp_menulist'), 
             'command',
             function() {
                 document.getElementById('note_btn').checked = false;
@@ -57,7 +58,7 @@ function edit_penalty_init() {
             },
             false
         );
-        document.getElementById('note_btn').addEventListener(
+        window.edit_standing_penalty_event_listeners.add(document.getElementById('note_btn'), 
             'command', 
             function() { 
                 document.getElementById('csp_menulist').setAttribute('label',''); 
@@ -65,7 +66,7 @@ function edit_penalty_init() {
             }, 
             false
         );
-        document.getElementById('alert_btn').addEventListener(
+        window.edit_standing_penalty_event_listeners.add(document.getElementById('alert_btn'), 
             'command', 
             function() { 
                 document.getElementById('csp_menulist').setAttribute('label',''); 
@@ -73,7 +74,7 @@ function edit_penalty_init() {
             }, 
             false
         );
-        document.getElementById('block_btn').addEventListener(
+        window.edit_standing_penalty_event_listeners.add(document.getElementById('block_btn'), 
             'command', 
             function() { 
                 document.getElementById('csp_menulist').setAttribute('label',''); 
@@ -81,10 +82,10 @@ function edit_penalty_init() {
             }, 
             false
         );
-        document.getElementById('cancel_btn').addEventListener(
+        window.edit_standing_penalty_event_listeners.add(document.getElementById('cancel_btn'), 
             'command', function() { window.close(); }, false
         );
-        document.getElementById('apply_btn').addEventListener(
+        window.edit_standing_penalty_event_listeners.add(document.getElementById('apply_btn'), 
             'command', 
             function() {
                 var note = document.getElementById('note_tb').value;
@@ -113,6 +114,16 @@ function edit_penalty_init() {
 
 }
 
+function edit_penalty_cleanup() {
+    try {
+        window.edit_standing_penalty_event_listeners.removeAll();
+    } catch(E) {
+        var err_prefix = 'standing_penalties.js -> penalty_cleanup() : ';
+        if (error) error.standard_unexpected_error_alert(err_prefix,E); else alert(err_prefix + E);
+    }
+
+}
+
 function build_penalty_menu() {
     try {
 
diff --git a/Open-ILS/xul/staff_client/server/patron/edit_standing_penalty.xul b/Open-ILS/xul/staff_client/server/patron/edit_standing_penalty.xul
index d27c001..771ae57 100644
--- a/Open-ILS/xul/staff_client/server/patron/edit_standing_penalty.xul
+++ b/Open-ILS/xul/staff_client/server/patron/edit_standing_penalty.xul
@@ -19,6 +19,7 @@
 
 <window id="edit_penalty_win" 
     onload="try { edit_penalty_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { edit_penalty_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     oils_persist="height width sizemode"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
     title="&staff.patron_display.edit_penalty_dialog.title;">
diff --git a/Open-ILS/xul/staff_client/server/patron/hold_cancel.js b/Open-ILS/xul/staff_client/server/patron/hold_cancel.js
index 4adbcc1..2f24eaf 100644
--- a/Open-ILS/xul/staff_client/server/patron/hold_cancel.js
+++ b/Open-ILS/xul/staff_client/server/patron/hold_cancel.js
@@ -25,10 +25,11 @@ function hold_cancel_init() {
         build_cancel_reason_menu();
 
         /* set widget behavior */
-        document.getElementById('cancel_btn').addEventListener(
+        window.hold_cancel_event_listeners = new EventListenerList();
+        window.hold_cancel_event_listeners.add(document.getElementById('cancel_btn'), 
             'command', function() { window.close(); }, false
         );
-        document.getElementById('apply_btn').addEventListener(
+        window.hold_cancel_event_listeners.add(document.getElementById('apply_btn'), 
             'command', 
             function() {
                 var note = document.getElementById('note_tb').value;
@@ -49,6 +50,16 @@ function hold_cancel_init() {
 
 }
 
+function hold_cancel_cleanup() {
+    try {
+        window.hold_cancel_event_listeners.removeAll();
+    } catch(E) {
+        var err_prefix = 'hold_cancel.js -> hold_cancel_cleanup() : ';
+        if (error) error.standard_unexpected_error_alert(err_prefix,E); else alert(err_prefix + E);
+    }
+
+}
+
 function build_cancel_reason_menu() {
     try {
 
diff --git a/Open-ILS/xul/staff_client/server/patron/hold_cancel.xul b/Open-ILS/xul/staff_client/server/patron/hold_cancel.xul
index fb3830c..d2da173 100644
--- a/Open-ILS/xul/staff_client/server/patron/hold_cancel.xul
+++ b/Open-ILS/xul/staff_client/server/patron/hold_cancel.xul
@@ -19,6 +19,7 @@
 
 <window id="hold_cancel_win" 
     onload="try { hold_cancel_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { hold_cancel_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
     title="&staff.hold_list.cancel_hold_dialog.title;">
 
diff --git a/Open-ILS/xul/staff_client/server/patron/hold_details.js b/Open-ILS/xul/staff_client/server/patron/hold_details.js
index be34911..f583094 100644
--- a/Open-ILS/xul/staff_client/server/patron/hold_details.js
+++ b/Open-ILS/xul/staff_client/server/patron/hold_details.js
@@ -29,6 +29,14 @@ function my_init() {
     }
 }
 
+function my_cleanup() {
+    try {
+        g.list.cleanup();
+    } catch(E) {
+        try { g.error.standard_unexpected_error_alert('/xul/server/patron/hold_notices.xul',E); } catch(E) { alert('FIXME: ' + js2JSON(E)); }
+    }
+}
+
 function fetch_and_render_all(do_not_refresh_parent_interface) {
     try {
         if (!xulG.ahr_id) { return; }
diff --git a/Open-ILS/xul/staff_client/server/patron/hold_details.xul b/Open-ILS/xul/staff_client/server/patron/hold_details.xul
index 779b798..245a061 100644
--- a/Open-ILS/xul/staff_client/server/patron/hold_details.xul
+++ b/Open-ILS/xul/staff_client/server/patron/hold_details.xul
@@ -20,6 +20,7 @@
 
 <window id="hold_notices_win" width="700" height="550" oils_persist="sizemode width height"
     onload="try{ my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }" title="&staff.patron.hold_notices.title;"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/holds.js b/Open-ILS/xul/staff_client/server/patron/holds.js
index 9b15aef..eaa29c4 100644
--- a/Open-ILS/xul/staff_client/server/patron/holds.js
+++ b/Open-ILS/xul/staff_client/server/patron/holds.js
@@ -41,6 +41,7 @@ patron.holds.prototype = {
         var obj = this;
 
         dojo.require("openils.Util");
+        obj.event_listeners = new EventListenerList();
 
         obj.patron_id = params['patron_id'];
         obj.patron_barcode = params['patron_barcode'];
@@ -1632,6 +1633,13 @@ patron.holds.prototype = {
 
     },
 
+    'cleanup' : function() {
+        var obj = this;
+        obj.controller.cleanup();
+        obj.list.cleanup();
+        obj.event_listeners.removeAll();
+    },
+
     'determine_hold_interface_type' : function() {
         var obj = this;
         if (obj.patron_id) { /*************************************************** PATRON ******************************/
@@ -1825,7 +1833,7 @@ patron.holds.prototype = {
                 var ml = util.widgets.make_menulist( list_data[0], obj.data.list.au[0].ws_ou() );
                 ml.setAttribute('id','lib_menu');
                 x.appendChild( ml );
-                ml.addEventListener(
+                obj.event_listeners.add(ml, 
                     'command',
                     function(ev) {
                         obj.filter_lib = ev.target.value;
diff --git a/Open-ILS/xul/staff_client/server/patron/holds.xul b/Open-ILS/xul/staff_client/server/patron/holds.xul
index f7f03fc..47eb367 100644
--- a/Open-ILS/xul/staff_client/server/patron/holds.xul
+++ b/Open-ILS/xul/staff_client/server/patron/holds.xul
@@ -21,6 +21,7 @@
 
 <window id="holds_win" active="true" 
     onload="try { font_helper(); persist_helper(); my_init(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
@@ -65,6 +66,16 @@
             }
         }
 
+        function my_cleanup() {
+            try {
+                g.holds.cleanup();
+            } catch(E) {
+                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/holds.xul', E]);
+                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+                alert(err_msg);
+            }
+        }
+
         function default_focus() { try { document.getElementById('holds_print').focus(); } catch(E) { } }
 
     ]]>
diff --git a/Open-ILS/xul/staff_client/server/patron/info_group.js b/Open-ILS/xul/staff_client/server/patron/info_group.js
index 60f754f..a9407ce 100644
--- a/Open-ILS/xul/staff_client/server/patron/info_group.js
+++ b/Open-ILS/xul/staff_client/server/patron/info_group.js
@@ -29,6 +29,16 @@ function my_init() {
     }
 }
 
+function my_cleanup() {
+    try {
+        list.cleanup();
+    } catch(E) {
+        var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/info_group.xul', E]);
+        try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+        alert(err_msg);
+    }
+}
+
 function retrieve_money_summaries() {
     try {
         JSAN.use('util.money');
diff --git a/Open-ILS/xul/staff_client/server/patron/info_group.xul b/Open-ILS/xul/staff_client/server/patron/info_group.xul
index 9e8777e..388efa2 100644
--- a/Open-ILS/xul/staff_client/server/patron/info_group.xul
+++ b/Open-ILS/xul/staff_client/server/patron/info_group.xul
@@ -20,6 +20,7 @@
 
 <window id="patron_info_group_win" width="700" height="550" active="true"
     onload="try{ my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/info_notes.xul b/Open-ILS/xul/staff_client/server/patron/info_notes.xul
index 133eec5..ab45e78 100644
--- a/Open-ILS/xul/staff_client/server/patron/info_notes.xul
+++ b/Open-ILS/xul/staff_client/server/patron/info_notes.xul
@@ -20,6 +20,7 @@
 
 <window id="patron_info_win" width="700" height="550"
     onload="try{ my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
@@ -54,6 +55,8 @@
 
                 g.new_note = false;
 
+                g.info_notes_event_listeners = new EventListenerList();
+
                 refresh();
 
             } catch(E) {
@@ -63,6 +66,16 @@
             }
         }
 
+        function my_cleanup() {
+            try {
+                g.info_notes_event_listeners.removeAll();
+            } catch(E) {
+                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/info_notes.xul', E]);
+                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+                alert(err_msg);
+            }
+        }
+
         function refresh() {
             retrieve_notes(); render_notes();
         }
@@ -124,7 +137,7 @@
                 btn1.setAttribute('label',$("patronStrings").getString('staff.patron.info_notes.render_notes.btn1.delete_note.label'));
                 btn1.setAttribute('image',"/xul/server/skin/media/images/up_arrow.gif");
 
-                btn1.addEventListener(
+                g.info_notes_event_listeners.add(btn1, 
                     'command',
                     function(id){ 
                         return function() { 
@@ -153,7 +166,7 @@
                     btn2.setAttribute('label',$("patronStrings").getString('staff.patron.info_notes.render_notes.btn2.print_note.label'));
                     btn2.setAttribute('image',"/xul/server/skin/media/images/up_arrow.gif");
 
-                    btn2.addEventListener(
+                    g.info_notes_event_listeners.add(btn2, 
                         'command',
                         function(id){ return function() { 
                             try {
diff --git a/Open-ILS/xul/staff_client/server/patron/info_stat_cats.xul b/Open-ILS/xul/staff_client/server/patron/info_stat_cats.xul
index 4318313..400aa67 100644
--- a/Open-ILS/xul/staff_client/server/patron/info_stat_cats.xul
+++ b/Open-ILS/xul/staff_client/server/patron/info_stat_cats.xul
@@ -20,6 +20,7 @@
 
 <window id="patron_info_stat_cats_win" width="700" height="550"
     onload="try{ my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try{  persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/info_surveys.xul b/Open-ILS/xul/staff_client/server/patron/info_surveys.xul
index 66231c3..c0fb29b 100644
--- a/Open-ILS/xul/staff_client/server/patron/info_surveys.xul
+++ b/Open-ILS/xul/staff_client/server/patron/info_surveys.xul
@@ -20,6 +20,7 @@
 
 <window id="patron_info_surveys_win" width="700" height="550"
     onload="try{ my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try{ persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/items.js b/Open-ILS/xul/staff_client/server/patron/items.js
index 47fa5e7..7d2b65a 100644
--- a/Open-ILS/xul/staff_client/server/patron/items.js
+++ b/Open-ILS/xul/staff_client/server/patron/items.js
@@ -225,6 +225,12 @@ patron.items.prototype = {
         obj.controller.view.cmd_show_catalog2.setAttribute('disabled','true');
     },
 
+    'cleanup' : function() {
+        var obj = this;
+        obj.list.cleanup();
+        obj.list2.cleanup();
+    },
+
     'show_noncats' : function() {
         var obj = this; var checkout = {};
         try {
diff --git a/Open-ILS/xul/staff_client/server/patron/items.xul b/Open-ILS/xul/staff_client/server/patron/items.xul
index 6faf415..0c7c537 100644
--- a/Open-ILS/xul/staff_client/server/patron/items.xul
+++ b/Open-ILS/xul/staff_client/server/patron/items.xul
@@ -21,6 +21,7 @@
 
 <window id="items_win" active="true" 
     onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
@@ -58,6 +59,16 @@
             }
         }
 
+        function my_cleanup() {
+            try {
+                g.items.cleanup();
+            } catch(E) {
+                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/items.xul', E]);
+                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+                alert(err_msg);
+            }
+        }
+
         function default_focus() { try { var x = document.getElementById('noncat'); x.focus(); } catch(E) { try { g.error.sdump('D_ERROR','item.xul, default_focus: ' + E); } catch(F) { dump(E); } } }
 
     ]]>
diff --git a/Open-ILS/xul/staff_client/server/patron/new_standing_penalty.js b/Open-ILS/xul/staff_client/server/patron/new_standing_penalty.js
index ddfd645..73c40cb 100644
--- a/Open-ILS/xul/staff_client/server/patron/new_standing_penalty.js
+++ b/Open-ILS/xul/staff_client/server/patron/new_standing_penalty.js
@@ -30,7 +30,8 @@ function new_penalty_init() {
         }
 
         /* set widget behavior */
-        document.getElementById('csp_menulist').addEventListener(
+        window.new_standing_penalty_event_listeners = new EventListenerList();
+        window.new_standing_penalty_event_listeners.add(document.getElementById('csp_menulist'), 
             'command',
             function() {
                 document.getElementById('note_btn').checked = false;
@@ -39,7 +40,7 @@ function new_penalty_init() {
             },
             false
         );
-        document.getElementById('note_btn').addEventListener(
+        window.new_standing_penalty_event_listeners.add(document.getElementById('note_btn'), 
             'command', 
             function() { 
                 document.getElementById('csp_menulist').setAttribute('label',''); 
@@ -47,7 +48,7 @@ function new_penalty_init() {
             }, 
             false
         );
-        document.getElementById('alert_btn').addEventListener(
+        window.new_standing_penalty_event_listeners.add(document.getElementById('alert_btn'), 
             'command', 
             function() { 
                 document.getElementById('csp_menulist').setAttribute('label',''); 
@@ -55,7 +56,7 @@ function new_penalty_init() {
             }, 
             false
         );
-        document.getElementById('block_btn').addEventListener(
+        window.new_standing_penalty_event_listeners.add(document.getElementById('block_btn'), 
             'command', 
             function() { 
                 document.getElementById('csp_menulist').setAttribute('label',''); 
@@ -63,10 +64,10 @@ function new_penalty_init() {
             }, 
             false
         );
-        document.getElementById('cancel_btn').addEventListener(
+        window.new_standing_penalty_event_listeners.add(document.getElementById('cancel_btn'), 
             'command', function() { window.close(); }, false
         );
-        document.getElementById('apply_btn').addEventListener(
+        window.new_standing_penalty_event_listeners.add(document.getElementById('apply_btn'), 
             'command', 
             function() {
                 var note = document.getElementById('note_tb').value;
@@ -96,6 +97,16 @@ function new_penalty_init() {
 
 }
 
+function new_penalty_cleanup() {
+    try {
+        window.new_standing_penalty_event_listeners.removeAll();
+    } catch(E) {
+        var err_prefix = 'standing_penalties.js -> penalty_cleanup() : ';
+        if (error) error.standard_unexpected_error_alert(err_prefix,E); else alert(err_prefix + E);
+    }
+
+}
+
 function build_penalty_menu() {
     try {
 
diff --git a/Open-ILS/xul/staff_client/server/patron/new_standing_penalty.xul b/Open-ILS/xul/staff_client/server/patron/new_standing_penalty.xul
index 7e9271b..cef7264 100644
--- a/Open-ILS/xul/staff_client/server/patron/new_standing_penalty.xul
+++ b/Open-ILS/xul/staff_client/server/patron/new_standing_penalty.xul
@@ -19,6 +19,7 @@
 
 <window id="new_penalty_win" 
     onload="try { new_penalty_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { new_penalty_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     oils_persist="height width sizemode"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
     title="&staff.patron_display.apply_penalty_dialog.title;">
diff --git a/Open-ILS/xul/staff_client/server/patron/place_hold.js b/Open-ILS/xul/staff_client/server/patron/place_hold.js
index 4dd8423..62049e7 100644
--- a/Open-ILS/xul/staff_client/server/patron/place_hold.js
+++ b/Open-ILS/xul/staff_client/server/patron/place_hold.js
@@ -20,7 +20,8 @@ function my_init() {
         populate_hold_usr_textbox();
         populate_pickup_lib_menu();
 
-        $('request_btn').addEventListener(
+        window.place_hold_event_listeners = new EventListenerList();
+        window.place_hold_event_listeners.add($('request_btn'), 
             'command',
             function(ev) {
                 make_request(copy_ids,false);
@@ -35,6 +36,14 @@ function my_init() {
     }
 }
 
+function my_cleanup() {
+    try {
+        window.place_hold_event_listeners.removeAll();
+    } catch(E) {
+        alert('Error in place_hold.js, my_init(): ' + E);
+    }
+}
+
 function make_request(copy_ids,override) {
     try {
 
@@ -134,7 +143,7 @@ function handle_failures(failures,failed_targets) {
                 )
             );
             addCSSClass(err_msg,'click_link');
-            err_msg.addEventListener(
+            window.place_hold_event_listeners.add(err_msg, 
                 'click',
                 function(copy_ids) {
                     return function(ev) {
@@ -156,7 +165,7 @@ function handle_failures(failures,failed_targets) {
             );
             err_box.appendChild(retry_btn);
 
-            retry_btn.addEventListener(
+            window.place_hold_event_listeners.add(retry_btn, 
                 'command',
                 function(copy_ids) {
                     return function(ev) {
@@ -177,7 +186,7 @@ function handle_failures(failures,failed_targets) {
             );
             err_box.appendChild(override_btn);
 
-            override_btn.addEventListener(
+            window.place_hold_event_listeners.add(override_btn, 
                 'command',
                 function(copy_ids) {
                     return function(ev) {
@@ -200,13 +209,13 @@ function handle_failures(failures,failed_targets) {
 function set_remaining_event_listeners() {
     try {
 
-        $('hold_type_menu').addEventListener(
+        window.place_hold_event_listeners.add($('hold_type_menu'), 
             'command',
             function(ev) { oils_lock_page(); },
             false
         );
 
-        $('cancel_btn').addEventListener(
+        window.place_hold_event_listeners.add($('cancel_btn'), 
             'command',
             function(ev) { xulG.close_tab(); },
             false
@@ -231,7 +240,7 @@ function populate_hold_usr_textbox() {
         'value',
         patron.util.format_name(au_obj)
     );
-    $('hold_usr_textbox').addEventListener(
+    window.place_hold_event_listeners.add($('hold_usr_textbox'), 
         'change',
         function(ev) {
             try {
@@ -288,7 +297,7 @@ function populate_pickup_lib_menu() {
 
         $('pickup_lib_menu_placeholder').appendChild(ml);
 
-        ml.addEventListener(
+        window.place_hold_event_listeners.add(ml, 
             'command',
             function(ev) { oils_lock_page(); },
             false
diff --git a/Open-ILS/xul/staff_client/server/patron/place_hold.xul b/Open-ILS/xul/staff_client/server/patron/place_hold.xul
index afa0a55..21c59b2 100644
--- a/Open-ILS/xul/staff_client/server/patron/place_hold.xul
+++ b/Open-ILS/xul/staff_client/server/patron/place_hold.xul
@@ -19,6 +19,7 @@
 
 <window id="place_hold_win" 
     onload="try{my_init();font_helper();persist_helper();}catch(E){alert(E);}"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- /////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/search_form.js b/Open-ILS/xul/staff_client/server/patron/search_form.js
index 7f58952..5fadf55 100644
--- a/Open-ILS/xul/staff_client/server/patron/search_form.js
+++ b/Open-ILS/xul/staff_client/server/patron/search_form.js
@@ -13,6 +13,7 @@ patron.search_form.prototype = {
     'init' : function( params ) {
 
         var obj = this;
+        obj.event_listeners = new EventListenerList();
 
         // The bulk of params.query is getting parsed/rendered by obj.controller.init below, and will be reconstituted from possibly modified XUL elements upon Submit.
         // But we're going to let search_limit and search_sort be configurable now by those spawning this interface, and let's assume there are no corresponding widgets for now.  
@@ -251,7 +252,7 @@ patron.search_form.prototype = {
         obj.controller.render();
         var nl = document.getElementsByTagName('textbox');
         for (var i = 0; i < nl.length; i++) {
-            nl[i].addEventListener('keypress',function(ev){
+            obj.event_listeners.add(nl[i], 'keypress', function(ev) {
                 if (ev.target.tagName != 'textbox') return;
                 if (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* enter on a mac */) setTimeout( function() { obj.submit(); }, 0);
             },false);
@@ -273,7 +274,7 @@ patron.search_form.prototype = {
                 }
             )
         );
-        ml.addEventListener('command', function() {
+        obj.event_listeners.add(ml, 'command', function() {
                 ml.parentNode.setAttribute('value',ml.value);
                 var file = new util.file('patron_search_prefs.'+obj.OpenILS.data.server_unadorned);
                 util.widgets.save_attributes(file, { 'search_depth_ml' : [ 'value' ], 'inactive' : [ 'value' ] });
@@ -291,7 +292,7 @@ patron.search_form.prototype = {
         }
 
         var cb = obj.controller.view.inactive;
-        cb.addEventListener('command',function() { 
+        obj.event_listeners.add(cb, 'command',function() {
                 cb.setAttribute('value',cb.checked ? "true" : "false");
                 var file = new util.file('patron_search_prefs.'+obj.OpenILS.data.server_unadorned);
                 util.widgets.save_attributes(file, { 'search_depth_ml' : [ 'value' ], 'inactive' : [ 'value' ] });
@@ -315,7 +316,7 @@ patron.search_form.prototype = {
                     }
                 )
             );
-            profile_ml.addEventListener('command', function() {
+            obj.event_listeners.add(profile_ml, 'command', function() {
                     profile_ml.parentNode.setAttribute('value', profile_ml.value);
                 }, false
             );
@@ -331,6 +332,12 @@ patron.search_form.prototype = {
         }
     },
 
+    'cleanup' : function() {
+        var obj = this;
+        obj.controller.cleanup();
+        obj.event_listeners.removeAll();    
+    }, 
+
     'on_submit' : function(q) {
         var msg = 'Query = ' + q;
         this.error.sdump('D_PATRON', msg);
diff --git a/Open-ILS/xul/staff_client/server/patron/search_form.xul b/Open-ILS/xul/staff_client/server/patron/search_form.xul
index 43a4fde..7822469 100644
--- a/Open-ILS/xul/staff_client/server/patron/search_form.xul
+++ b/Open-ILS/xul/staff_client/server/patron/search_form.xul
@@ -21,6 +21,7 @@
 
 <window id="patron_search_form_win" 
     onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
@@ -68,6 +69,16 @@
             }
         }
         
+        function my_cleanup() {
+            try {
+                g.search_form.cleanup();
+            } catch(E) {
+                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/search_form.xul', E]);
+                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+                alert(err_msg);
+            }
+        }
+
         function default_focus() {
             setTimeout(
                 function() {
diff --git a/Open-ILS/xul/staff_client/server/patron/search_form_horiz.xul b/Open-ILS/xul/staff_client/server/patron/search_form_horiz.xul
index 4e8f6af..ed0655b 100644
--- a/Open-ILS/xul/staff_client/server/patron/search_form_horiz.xul
+++ b/Open-ILS/xul/staff_client/server/patron/search_form_horiz.xul
@@ -21,6 +21,7 @@
 
 <window id="patron_search_form_win" 
     onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
@@ -67,6 +68,16 @@
                 alert(err_msg);
             }
         }
+
+        function my_cleanup() {
+            try {
+                g.search_form.cleanup();
+            } catch(E) {
+                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/search_form.xul', E]);
+                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+                alert(err_msg);
+            }
+        }
         
         function default_focus() {
             setTimeout(
diff --git a/Open-ILS/xul/staff_client/server/patron/search_result.js b/Open-ILS/xul/staff_client/server/patron/search_result.js
index e9e5f4a..8a77a71 100644
--- a/Open-ILS/xul/staff_client/server/patron/search_result.js
+++ b/Open-ILS/xul/staff_client/server/patron/search_result.js
@@ -73,6 +73,25 @@ patron.search_result.prototype = {
             },'mailing_')
         );
 
+        obj.dblclick_handler = function(ev) {
+            JSAN.use('util.functional');
+            var sel = obj.list.retrieve_selection();
+            var list = util.functional.map_list(
+                sel,
+                function(o) { return o.getAttribute('retrieve_id'); }
+            );
+            obj.controller.view.cmd_sel_clip.setAttribute('disabled', list.length < 1 );
+            if (typeof obj.on_dblclick == 'function') {
+                obj.on_dblclick(list);
+            }
+            if (typeof window.xulG == 'object' && typeof window.xulG.on_dblclick == 'function') {
+                obj.error.sdump('D_PATRON','patron.search_result: Calling external .on_dblclick()\n');
+                window.xulG.on_dblclick(list);
+            } else {
+                obj.error.sdump('D_PATRON','patron.search_result: No external .on_dblclick()\n');
+            }
+        };
+
         obj.list.init(
             {
                 'columns' : columns,
@@ -101,24 +120,7 @@ patron.search_result.prototype = {
                         }
                     );
                 },
-                'on_dblclick' : function(ev) {
-                    JSAN.use('util.functional');
-                    var sel = obj.list.retrieve_selection();
-                    var list = util.functional.map_list(
-                        sel,
-                        function(o) { return o.getAttribute('retrieve_id'); }
-                    );
-                    obj.controller.view.cmd_sel_clip.setAttribute('disabled', list.length < 1 );
-                    if (typeof obj.on_dblclick == 'function') {
-                        obj.on_dblclick(list);
-                    }
-                    if (typeof window.xulG == 'object' && typeof window.xulG.on_dblclick == 'function') {
-                        obj.error.sdump('D_PATRON','patron.search_result: Calling external .on_dblclick()\n');
-                        window.xulG.on_dblclick(list);
-                    } else {
-                        obj.error.sdump('D_PATRON','patron.search_result: No external .on_dblclick()\n');
-                    }
-                },
+                'on_dblclick' : obj.dblclick_handler,
                 'on_select' : function(ev) {
                     JSAN.use('util.functional');
                     var sel = obj.list.retrieve_selection();
@@ -184,6 +186,12 @@ patron.search_result.prototype = {
         if (obj.query) obj.search(obj.query);
     },
 
+    'cleanup' : function( params ) {
+        var obj = this;
+        obj.controller.cleanup();
+        obj.list.cleanup();
+    },
+
     'search' : function(query) {
         var obj = this;
         var search_hash = {};
diff --git a/Open-ILS/xul/staff_client/server/patron/search_result.xul b/Open-ILS/xul/staff_client/server/patron/search_result.xul
index 9546380..658eafc 100644
--- a/Open-ILS/xul/staff_client/server/patron/search_result.xul
+++ b/Open-ILS/xul/staff_client/server/patron/search_result.xul
@@ -21,6 +21,7 @@
 
 <window id="patron_search_result_win" 
     onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
@@ -63,6 +64,16 @@
             }
         }
 
+        function my_cleanup() {
+            try {
+                g.search_result.cleanup();
+            } catch(E) {
+                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/search_result.xul', E]);
+                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+                alert(err_msg);
+            }
+        }
+
     ]]>
     </script>
 
diff --git a/Open-ILS/xul/staff_client/server/patron/staged.js b/Open-ILS/xul/staff_client/server/patron/staged.js
index 45e1567..246a57d 100644
--- a/Open-ILS/xul/staff_client/server/patron/staged.js
+++ b/Open-ILS/xul/staff_client/server/patron/staged.js
@@ -33,13 +33,14 @@ function staged_init() {
 
         dojo.require('openils.Util');
 
+        window.staged_event_listeners = new EventListenerList();
         populate_lib_menu();
         init_list();
         $('list_actions').appendChild( list.render_list_actions() );
         list.set_list_actions();
-        $('cmd_cancel').addEventListener('command', gen_event_handler('cancel'), false);
-        $('cmd_load').addEventListener('command', gen_event_handler('load'), false);
-        $('cmd_reload').addEventListener('command', function() { populate_list(); }, false);
+        window.staged_event_listeners.add($('cmd_cancel'), 'command', gen_event_handler('cancel'), false);
+        window.staged_event_listeners.add($('cmd_load'), 'command', gen_event_handler('load'), false);
+        window.staged_event_listeners.add($('cmd_reload'), 'command', function() { populate_list(); }, false);
         populate_list();
         default_focus();
 
@@ -49,6 +50,16 @@ function staged_init() {
     }
 }
 
+function staged_cleanup() {
+    try {
+        list.cleanup();
+        window.staged_event_listeners.removeAll();
+    } catch(E) {
+        var err_prefix = 'staged.js -> staged_cleanup() : ';
+        if (error) error.standard_unexpected_error_alert(err_prefix,E); else alert(err_prefix + E);
+    }
+}
+
 function populate_lib_menu() {
     try {
         JSAN.use('util.widgets');
@@ -64,7 +75,7 @@ function populate_lib_menu() {
             var ml = util.widgets.make_menulist( list_data[0], menu_lib );
             ml.setAttribute('id','lib_menu');
             x.appendChild( ml );
-            ml.addEventListener(
+            window.staged_event_listeners.add(ml, 
                 'command',
                 function(ev) {
                     menu_lib = ev.target.value;
diff --git a/Open-ILS/xul/staff_client/server/patron/staged.xul b/Open-ILS/xul/staff_client/server/patron/staged.xul
index f7fb70f..18b3140 100644
--- a/Open-ILS/xul/staff_client/server/patron/staged.xul
+++ b/Open-ILS/xul/staff_client/server/patron/staged.xul
@@ -18,6 +18,7 @@
 <?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
 
 <window id="staged_win" onload="try { font_helper(); persist_helper(); staged_init(); } catch(E) { alert(E); }"
+    onunload="try { staged_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/standing_penalties.js b/Open-ILS/xul/staff_client/server/patron/standing_penalties.js
index d36edf4..7b9f714 100644
--- a/Open-ILS/xul/staff_client/server/patron/standing_penalties.js
+++ b/Open-ILS/xul/staff_client/server/patron/standing_penalties.js
@@ -28,12 +28,13 @@ function penalty_init() {
 
         init_list();
         init_archived_list();
+        window.standing_penalties_event_listeners = new EventListenerList();
         document.getElementById('date1').year = document.getElementById('date1').year - 1;
-        document.getElementById('cmd_apply_penalty').addEventListener('command', handle_apply_penalty, false);
-        document.getElementById('cmd_remove_penalty').addEventListener('command', handle_remove_penalty, false);
-        document.getElementById('cmd_edit_penalty').addEventListener('command', handle_edit_penalty, false);
-        document.getElementById('cmd_archive_penalty').addEventListener('command', handle_archive_penalty, false);
-        document.getElementById('cmd_retrieve_archived_penalties').addEventListener('command', handle_retrieve_archived_penalties, false);
+        window.standing_penalties_event_listeners.add(document.getElementById('cmd_apply_penalty'), 'command', handle_apply_penalty, false);
+        window.standing_penalties_event_listeners.add(document.getElementById('cmd_remove_penalty'), 'command', handle_remove_penalty, false);
+        window.standing_penalties_event_listeners.add(document.getElementById('cmd_edit_penalty'), 'command', handle_edit_penalty, false);
+        window.standing_penalties_event_listeners.add(document.getElementById('cmd_archive_penalty'), 'command', handle_archive_penalty, false);
+        window.standing_penalties_event_listeners.add(document.getElementById('cmd_retrieve_archived_penalties'), 'command', handle_retrieve_archived_penalties, false);
         populate_list();
         default_focus();
 
@@ -43,6 +44,17 @@ function penalty_init() {
     }
 }
 
+function penalty_cleanup() {
+    try {
+        window.standing_penalties_event_listeners.removeAll();
+        list.cleanup();
+        archived_list.cleanup();
+    } catch(E) {
+        var err_prefix = 'standing_penalties.js -> penalty_cleanup() : ';
+        if (error) error.standard_unexpected_error_alert(err_prefix,E); else alert(err_prefix + E);
+    }
+}
+
 function init_list() {
     try {
 
diff --git a/Open-ILS/xul/staff_client/server/patron/standing_penalties.xul b/Open-ILS/xul/staff_client/server/patron/standing_penalties.xul
index a1b5d90..5571298 100644
--- a/Open-ILS/xul/staff_client/server/patron/standing_penalties.xul
+++ b/Open-ILS/xul/staff_client/server/patron/standing_penalties.xul
@@ -18,6 +18,7 @@
 <?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
 
 <window id="penalty_win" onload="try { penalty_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { penalty_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
diff --git a/Open-ILS/xul/staff_client/server/patron/summary.js b/Open-ILS/xul/staff_client/server/patron/summary.js
index 0b65cc4..6b73ff9 100644
--- a/Open-ILS/xul/staff_client/server/patron/summary.js
+++ b/Open-ILS/xul/staff_client/server/patron/summary.js
@@ -19,6 +19,7 @@ patron.summary.prototype = {
     'init' : function( params ) {
 
         var obj = this;
+        obj.event_listeners = new EventListenerList();
 
         obj.barcode = params['barcode'];
         obj.id = params['id'];
@@ -901,7 +902,7 @@ patron.summary.prototype = {
             var caption = document.getElementById("PatronSummaryContact_caption");
             var arrow = document.getAnonymousNodes(caption)[0];
             var gb_content = document.getAnonymousNodes(caption.parentNode)[1];
-            arrow.addEventListener(
+            obj.event_listeners.add(arrow,
                 'click',
                 function() {
                     setTimeout(
@@ -930,6 +931,14 @@ patron.summary.prototype = {
         }
     },
 
+    'cleanup' : function() {
+        var obj = this;
+        if (typeof obj.group_list != 'undefined') obj.group_list.cleanup();
+        if (typeof obj.stat_cat_list != 'undefined') obj.stat_cat_list.cleanup();
+        obj.controller.cleanup();
+        obj.event_listeners.removeAll();
+    },
+
     'retrieve' : function() {
 
         try {
diff --git a/Open-ILS/xul/staff_client/server/patron/summary.xul b/Open-ILS/xul/staff_client/server/patron/summary.xul
index cee959b..6990028 100644
--- a/Open-ILS/xul/staff_client/server/patron/summary.xul
+++ b/Open-ILS/xul/staff_client/server/patron/summary.xul
@@ -20,7 +20,8 @@
 <?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
 
 <window id="patron_summary_win" 
-    onload="try { font_helper(); my_init(); persist_helper(); } catch(E) { alert(E); }" onunload="try { observer.unregister(); } catch(E) { alert(E); }"
+    onload="try { font_helper(); my_init(); persist_helper(); } catch(E) { alert(E); }" 
+    onunload="try { my_cleanup(); persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
@@ -73,6 +74,17 @@
             }
         }
 
+        function my_cleanup() {
+            try {
+                observer.unregister();
+                g.summary.cleanup();
+            } catch(E) {
+                var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/summary.xul:my_init()', E]);
+                try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
+                alert(err_msg);
+            }
+        }
+
         function export_address(ev) {
             var action = ev.originalTarget.id;
             var a;
diff --git a/Open-ILS/xul/staff_client/server/patron/user_buckets.xul b/Open-ILS/xul/staff_client/server/patron/user_buckets.xul
index 18eb8b6..d534d77 100644
--- a/Open-ILS/xul/staff_client/server/patron/user_buckets.xul
+++ b/Open-ILS/xul/staff_client/server/patron/user_buckets.xul
@@ -19,6 +19,7 @@
 
 <window id="example_template_win" 
     onload="try { my_init(); font_helper(); persist_helper(); } catch(E) { alert(E); }"
+    onunload="try { persist_helper_cleanup(); } catch(E) { alert(E); }"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
     <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->

commit abbd9181ac45f3461f71cfe9d2896e3d24693804
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Thu Jan 24 12:27:34 2013 -0500

    LP#1086458: add more event listener tracking
    
    util.list and util.controller now have cleanup()
    methods that can be invoked to unregister the event
    listeners they create.
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/chrome/content/util/controller.js b/Open-ILS/xul/staff_client/chrome/content/util/controller.js
index facecfa..3174b23 100644
--- a/Open-ILS/xul/staff_client/chrome/content/util/controller.js
+++ b/Open-ILS/xul/staff_client/chrome/content/util/controller.js
@@ -16,6 +16,7 @@ util.controller.prototype = {
 
         if (typeof params.control_map == 'undefined') throw('util.controller.init: No control_map');
 
+        this.event_listeners = new EventListenerList();
         this.control_map = params.control_map;
         this.window_knows_me_by = params.window_knows_me_by;
         this.render_list = [];
@@ -38,7 +39,7 @@ util.controller.prototype = {
                                 cmd.setAttribute(ev_type, s);
                                 this.cmds[i] = this.control_map[i][1];
                             break;
-                            default: cmd.addEventListener(ev_type,this.control_map[i][1],false);
+                            default: this.event_listeners.add(cmd, ev_type,this.control_map[i][1],false);
                         }
                     }
                 }
@@ -47,6 +48,11 @@ util.controller.prototype = {
         }
     },
 
+    'cleanup' : function() {
+        var obj = this;
+        obj.event_listeners.removeAll();
+    },
+
     'render' : function(id,param) {
         for (var i in this.render_list) {
             try {
diff --git a/Open-ILS/xul/staff_client/chrome/content/util/list.js b/Open-ILS/xul/staff_client/chrome/content/util/list.js
index e9bf29a..8166016 100644
--- a/Open-ILS/xul/staff_client/chrome/content/util/list.js
+++ b/Open-ILS/xul/staff_client/chrome/content/util/list.js
@@ -36,6 +36,7 @@ util.list.prototype = {
 
         var obj = this;
         obj.scratch_data = {};
+        obj.event_listeners = new EventListenerList();
 
         // If set, save and restore columns as if the tree/list id was the value of columns_saved_under
         obj.columns_saved_under = params.columns_saved_under;
@@ -128,7 +129,8 @@ util.list.prototype = {
                 treecols.appendChild(treecol);
 
                 if (this.columns[i].type == 'checkbox') {
-                    treecol.addEventListener(
+                    obj.event_listeners.add(
+                        treecol,
                         'click',
                         function(ev) {
                             setTimeout(
@@ -143,7 +145,8 @@ util.list.prototype = {
                         false
                     );
                 } else {
-                    treecol.addEventListener(
+                    obj.event_listeners.add(
+                        treecol,
                         'sort_first_asc',
                         function(ev) {
                             dump('sort_first_asc\n');
@@ -157,7 +160,8 @@ util.list.prototype = {
                         },
                         false
                     );
-                    treecol.addEventListener(
+                    obj.event_listeners.add(
+                        treecol,
                         'sort_first_desc',
                         function(ev) {
                             dump('sort_first_desc\n');
@@ -171,7 +175,8 @@ util.list.prototype = {
                         },
                         false
                     );
-                    treecol.addEventListener(
+                    obj.event_listeners.add(
+                        treecol,
                         'sort_next_asc',
                         function(ev) {
                             dump('sort_next_asc\n');
@@ -184,7 +189,8 @@ util.list.prototype = {
                         },
                         false
                     );
-                    treecol.addEventListener(
+                    obj.event_listeners.add(
+                        treecol,
                         'sort_next_desc',
                         function(ev) {
                             dump('sort_next_desc\n');
@@ -198,7 +204,8 @@ util.list.prototype = {
                         false
                     );
 
-                    treecol.addEventListener(
+                    obj.event_listeners.add(
+                        treecol,
                         'click', 
                         function(ev) {
                             if (ev.button == 2 /* context menu click */ || ev.target.getAttribute('no_sort')) {
@@ -233,7 +240,8 @@ util.list.prototype = {
                         false
                     );
 
-                    treecol.addEventListener(
+                    obj.event_listeners.add(
+                        treecol,
                         'sort',
                         function(ev) {
                             if (!obj.first_sort) {
@@ -281,7 +289,8 @@ util.list.prototype = {
         if (typeof params.on_checkbox_toggle == 'function') {
             this.on_checkbox_toggle = params.on_checkbox_toggle;
         }
-        this.node.addEventListener(
+        obj.event_listeners.add(
+            this.node,
             'select',
             function(ev) {
                 if (typeof params.on_select == 'function') {
@@ -296,14 +305,16 @@ util.list.prototype = {
             false
         );
         if (typeof params.on_click == 'function') {
-            this.node.addEventListener(
+            obj.event_listeners.add(
+                this.node,
                 'click',
                 params.on_click,
                 false
             );
         }
         if (typeof params.on_dblclick == 'function') {
-            this.node.addEventListener(
+            obj.event_listeners.add(
+                this.node,
                 'dblclick',
                 params.on_dblclick,
                 false
@@ -311,23 +322,27 @@ util.list.prototype = {
         }
 
         /*
-        this.node.addEventListener(
+        obj.event_listeners.add(
+            this.node,
             'mousemove',
             function(ev) { obj.detect_visible(); },
             false
         );
         */
-        this.node.addEventListener(
+        obj.event_listeners.add(
+            this.node,
             'keypress',
             function(ev) { obj.auto_retrieve(); },
             false
         );
-        this.node.addEventListener(
+        obj.event_listeners.add(
+            this.node,
             'click',
             function(ev) { obj.auto_retrieve(); },
             false
         );
-        window.addEventListener(
+        obj.event_listeners.add(
+            window,
             'resize',
             function(ev) { obj.auto_retrieve(); },
             false
@@ -345,7 +360,7 @@ util.list.prototype = {
         slider.addEventListener('command',function(){alert('slider command');},false);
         slider.addEventListener('scroll',function(){alert('slider scroll');},false);
         */
-        this.node.addEventListener('scroll',function(){ obj.auto_retrieve(); },false);
+        obj.event_listeners.add(this.node, 'scroll',function(){ obj.auto_retrieve(); },false);
 
         this.restores_columns(params);
     },
@@ -372,6 +387,11 @@ util.list.prototype = {
         }
     },
 
+    'cleanup' : function () {
+        var obj = this;
+        obj.event_listeners.removeAll();
+    },
+
     'save_columns' : function (params) {
         var obj = this;
         if (obj.data.hash.aous['gui.disable_local_save_columns']) {
@@ -628,7 +648,8 @@ util.list.prototype = {
         obj.put_retrieving_label(treerow);
 
         if (typeof params.retrieve_row == 'function' || typeof this.retrieve_row == 'function') {
-            treerow.addEventListener(
+            obj.event_listeners.add(
+                treerow,
                 'flesh',
                 function() {
 
@@ -692,7 +713,8 @@ util.list.prototype = {
                 }
             }
         } else {
-            treerow.addEventListener(
+            obj.event_listeners.add(
+                treerow,
                 'flesh',
                 function() {
                     //dump('fleshing anon\n');
@@ -790,7 +812,8 @@ util.list.prototype = {
 
             s += 'found a retrieve_row function\n';
 
-            treerow.addEventListener(
+            obj.event_listeners.add(
+                treerow,
                 'flesh',
                 function() {
 
@@ -858,7 +881,8 @@ util.list.prototype = {
 
             s += 'did not find a retrieve_row function\n';
 
-            treerow.addEventListener(
+            obj.event_listeners.add(
+                treerow,
                 'flesh',
                 function() {
                     //dump('fleshing anon\n');
@@ -1917,7 +1941,8 @@ util.list.prototype = {
         try {
             var x = document.getElementById(obj.node.id + '_clipfield');
             if (x) {
-                x.addEventListener(
+                obj.event_listeners.add(
+                    x,
                     'command',
                     function() {
                         obj.clipboard(params);
@@ -1930,7 +1955,8 @@ util.list.prototype = {
             }
             x = document.getElementById(obj.node.id + '_csv_to_clipboard');
             if (x) {
-                x.addEventListener(
+                obj.event_listeners.add(
+                    x,
                     'command',
                     function() {
                         obj.dump_csv_to_clipboard(params);
@@ -1943,7 +1969,8 @@ util.list.prototype = {
             }
             x = document.getElementById(obj.node.id + '_csv_to_printer');
             if (x) {
-                x.addEventListener(
+                obj.event_listeners.add(
+                    x,
                     'command',
                     function() {
                         obj.dump_csv_to_printer(params);
@@ -1956,7 +1983,8 @@ util.list.prototype = {
             }
             x = document.getElementById(obj.node.id + '_extended_to_printer');
             if (x) {
-                x.addEventListener(
+                obj.event_listeners.add(
+                    x,
                     'command',
                     function() {
                         obj.dump_extended_format_to_printer(params);
@@ -1970,7 +1998,8 @@ util.list.prototype = {
 
             x = document.getElementById(obj.node.id + '_csv_to_file');
             if (x) {
-                x.addEventListener(
+                obj.event_listeners.add(
+                    x,
                     'command',
                     function() {
                         obj.dump_csv_to_file(params);
@@ -1983,7 +2012,8 @@ util.list.prototype = {
             }
             x = document.getElementById(obj.node.id + '_save_columns');
             if (x) {
-                x.addEventListener(
+                obj.event_listeners.add(
+                    x,
                     'command',
                     function() {
                         obj.save_columns(params);

commit 70f7c8a9671a9c62552aac4ee216cac24b545ed4
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Thu Jan 24 12:02:57 2013 -0500

    LP#1086458: add way to clean up persist_helper event listeners
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js b/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js
index e0b6217..3f58aa6 100644
--- a/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js
+++ b/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js
@@ -256,6 +256,7 @@
             } else {
                 base_key_suffix = '';
             }
+            window.persist_helper_event_listeners = new EventListenerList();
 
             function gen_event_handler(etype,node) {
                 return function(ev) {
@@ -408,12 +409,12 @@
                     }
                 }
                 if (cmd_el) {
-                    cmd_el.addEventListener(
+                    window.persist_helper_event_listeners.add(cmd_el, 
                         'command',
                         gen_event_handler('command',cmd_el),
                         false
                     );
-                    cmd_el.addEventListener(
+                    window.persist_helper_event_listeners.add(cmd_el, 
                         'oils_persist',
                         gen_oils_persist_handler( base_key, nodes[i] ),
                         false
@@ -439,13 +440,13 @@
                         }
                     }
                     for (var j = 0; j < event_types.length; j++) {
-                        node.addEventListener(
+                        window.persist_helper_event_listeners.add(node, 
                             event_types[j],
                             gen_event_handler(event_types[j],node),
                             false
                         );
                     }
-                    node.addEventListener(
+                    window.persist_helper_event_listeners.add(node, 
                         'oils_persist',
                         gen_oils_persist_handler( base_key, node ),
                         false
@@ -457,6 +458,14 @@
         }
     }
 
+    function persist_helper_cleanup() {
+        try {
+            window.persist_helper_event_listeners.removeAll();
+        } catch(E) {
+            alert('Error in persist_helper_cleanup(): ' + E);
+        }
+    }
+
     function getKeys(o) {
         var keys = [];
         for (var k in o) keys.push(k);

commit f8be2b0a1d71ee8b7d565eb7b838bd58e87a3569
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Thu Jan 24 11:56:30 2013 -0500

    LP#1086458: add class to manage event listeners
    
    EventListenerList allows one to maintain a list
    of event listeners, then remove them all when it's
    time to clean up a window.
    
    Usage is:
    
    var list = new EventListenerList();
    // attach an event listener
    list.add(node, 'command', function(ev) { alert('BOO!'); }, false);
    ...
    // get rid of them
    list.removeAll();
    
    Based on an idea by Jason Etheridge.
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>

diff --git a/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js b/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js
index 3928960..e0b6217 100644
--- a/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js
+++ b/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js
@@ -2,6 +2,43 @@
         xulG = window.arguments[0];
     }
 
+    function EventListenerList() {
+        this._listeners = [];
+        return this;
+    }
+
+    EventListenerList.prototype = {
+        'add' : function(node, type, listener, useCapture) {
+            try {
+                node.addEventListener(type,listener,useCapture);
+                this._listeners.push({
+                    'node' : node,
+                    'type' : type,
+                    'listener' : listener,
+                    'useCapture' : useCapture
+                });
+            } catch(E) {
+                alert(location.href + ' Error adding event listener ' + type + ': ' + E);
+            }
+        },
+
+        'removeAll' : function() {
+            try {
+                if (typeof this._listeners != 'undefined') {
+                    for (var i = 0; i < this._listeners.length; i++) {
+                        this._listeners[i].node.removeEventListener(
+                            this._listeners[i].type,
+                            this._listeners[i].listener,
+                            this._listeners[i].useCapture
+                        );
+                    }
+                }
+            } catch(E) {
+                alert(location.href + ' Error in unloadEventListeners(): ' + E);
+            }
+        }
+    }
+
     function $(id) { return document.getElementById(id); }
 
     function oils_unsaved_data_V() {

-----------------------------------------------------------------------

Summary of changes:
 Open-ILS/xul/staff_client/Makefile.am              |    1 +
 .../chrome/content/OpenILS/event_util.js           |   40 ++++++++++
 .../chrome/content/OpenILS/global_util.js          |   17 +++-
 .../chrome/content/OpenILS/util_overlay_chrome.xul |    1 +
 .../content/OpenILS/util_overlay_offline.xul       |    1 +
 .../staff_client/chrome/content/main/bindings.xml  |   18 +++++
 .../xul/staff_client/chrome/content/main/main.xul  |    1 +
 .../staff_client/chrome/content/util/controller.js |    8 ++-
 .../xul/staff_client/chrome/content/util/list.js   |   80 +++++++++++++------
 .../staff_client/chrome/content/util/shell.html    |    1 +
 .../staff_client/server/OpenILS/util_overlay.xul   |    1 +
 .../staff_client/server/admin/printer_settings.xul |    1 +
 .../staff_client/server/admin/upload_xacts.xhtml   |    1 +
 Open-ILS/xul/staff_client/server/circ/checkout.js  |   10 ++-
 Open-ILS/xul/staff_client/server/circ/checkout.xul |   13 +++
 Open-ILS/xul/staff_client/server/index.xhtml       |    2 +
 .../server/locale/en-US/patron.properties          |    1 +
 .../staff_client/server/patron/barcode_entry.xul   |   14 +++-
 Open-ILS/xul/staff_client/server/patron/bill2.js   |   39 +++++++---
 Open-ILS/xul/staff_client/server/patron/bill2.xul  |    1 +
 .../staff_client/server/patron/bill_cc_info.xul    |    1 +
 .../staff_client/server/patron/bill_check_info.xul |    1 +
 .../xul/staff_client/server/patron/bill_details.js |   20 ++++-
 .../staff_client/server/patron/bill_details.xul    |    1 +
 .../xul/staff_client/server/patron/bill_history.js |   26 +++++-
 .../staff_client/server/patron/bill_history.xul    |    1 +
 .../xul/staff_client/server/patron/bill_wizard.js  |   14 +++-
 .../xul/staff_client/server/patron/bill_wizard.xul |    1 +
 Open-ILS/xul/staff_client/server/patron/display.js |   45 +++++++----
 .../xul/staff_client/server/patron/display.xul     |   11 +++
 .../staff_client/server/patron/display_horiz.xul   |   11 +++
 .../server/patron/edit_standing_penalty.js         |   23 ++++--
 .../server/patron/edit_standing_penalty.xul        |    1 +
 .../xul/staff_client/server/patron/hold_cancel.js  |   15 +++-
 .../xul/staff_client/server/patron/hold_cancel.xul |    1 +
 .../xul/staff_client/server/patron/hold_details.js |    9 ++
 .../staff_client/server/patron/hold_details.xul    |    1 +
 Open-ILS/xul/staff_client/server/patron/holds.js   |   11 +++-
 Open-ILS/xul/staff_client/server/patron/holds.xul  |   11 +++
 .../xul/staff_client/server/patron/info_group.js   |   11 +++
 .../xul/staff_client/server/patron/info_group.xul  |    1 +
 .../xul/staff_client/server/patron/info_notes.xul  |   17 ++++-
 .../staff_client/server/patron/info_stat_cats.xul  |    1 +
 .../staff_client/server/patron/info_surveys.xul    |    1 +
 Open-ILS/xul/staff_client/server/patron/items.js   |    8 ++
 Open-ILS/xul/staff_client/server/patron/items.xul  |   11 +++
 .../server/patron/new_standing_penalty.js          |   23 ++++--
 .../server/patron/new_standing_penalty.xul         |    1 +
 .../xul/staff_client/server/patron/place_hold.js   |   26 +++++--
 .../xul/staff_client/server/patron/place_hold.xul  |    1 +
 .../xul/staff_client/server/patron/search_form.js  |   15 +++-
 .../xul/staff_client/server/patron/search_form.xul |   11 +++
 .../server/patron/search_form_horiz.xul            |   11 +++
 .../staff_client/server/patron/search_result.js    |   45 +++++++-----
 .../staff_client/server/patron/search_result.xul   |   11 +++
 Open-ILS/xul/staff_client/server/patron/staged.js  |   20 ++++-
 Open-ILS/xul/staff_client/server/patron/staged.xul |    1 +
 .../server/patron/standing_penalties.js            |   24 +++++-
 .../server/patron/standing_penalties.xul           |    1 +
 Open-ILS/xul/staff_client/server/patron/summary.js |   17 ++++-
 .../xul/staff_client/server/patron/summary.xul     |   14 +++-
 .../staff_client/server/patron/user_buckets.xul    |    1 +
 62 files changed, 599 insertions(+), 128 deletions(-)
 create mode 100644 Open-ILS/xul/staff_client/chrome/content/OpenILS/event_util.js


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list