[open-ils-commits] [GIT] Evergreen ILS branch master updated. ca7d04bc908b964f2bcb1b849f1d402ee90f0931

Evergreen Git git at git.evergreen-ils.org
Mon Mar 4 14:51:19 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, master has been updated
       via  ca7d04bc908b964f2bcb1b849f1d402ee90f0931 (commit)
       via  2f65adc476a629da56911370fe48eb25f9e7474f (commit)
       via  0876d97f6ff74157d2fecb5cf762573bad74acbb (commit)
       via  219d0cff7b4f49843cc73b423a2177d72b2b476e (commit)
       via  0f074b31b4ded0c7db3565b3a51c216b92afeaf8 (commit)
       via  f0f36a7b02e5dece844929aafdb135614732425c (commit)
       via  131da362381e8d9a53a3bbb68e46d6c7791294b0 (commit)
       via  5e31934651e0aacc0c98f361e54fe3d8664134df (commit)
       via  e6a56b322420fbed19d2bab59718a19f7374f57b (commit)
       via  5bea275a8fbfb3d788ee3bc10867a9e45b0d9307 (commit)
       via  5386af67d7be2926e85966e198525e35d5e76b81 (commit)
       via  e227c232fd8067177334be369a584af8497666dc (commit)
       via  df56b77591d1b4c4bd50dfc83d37f10117817b2e (commit)
      from  0910a95da94800da094c81b2efd7fa394c34794c (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 ca7d04bc908b964f2bcb1b849f1d402ee90f0931
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 2f65adc476a629da56911370fe48eb25f9e7474f
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 0876d97f6ff74157d2fecb5cf762573bad74acbb
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 219d0cff7b4f49843cc73b423a2177d72b2b476e
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 0f074b31b4ded0c7db3565b3a51c216b92afeaf8
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 f0f36a7b02e5dece844929aafdb135614732425c
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 2e165a6..a27b5cb 100644
--- a/Open-ILS/xul/staff_client/Makefile.am
+++ b/Open-ILS/xul/staff_client/Makefile.am
@@ -102,6 +102,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 f7abba4..fabe682 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 324c017..1b36f3a 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 131da362381e8d9a53a3bbb68e46d6c7791294b0
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 74e53fc..ffac5d1 100644
--- a/Open-ILS/xul/staff_client/server/patron/display.js
+++ b/Open-ILS/xul/staff_client/server/patron/display.js
@@ -688,6 +688,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 5e31934651e0aacc0c98f361e54fe3d8664134df
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 10d6748..a9af71d 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 64d244d..a2fc061 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 e6a56b322420fbed19d2bab59718a19f7374f57b
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 a1231a5..da375fe 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 5bea275a8fbfb3d788ee3bc10867a9e45b0d9307
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 9b6089c..a1231a5 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 567a40c..cee408d 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 83bf51c..10d6748 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();
@@ -154,7 +166,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( 
@@ -171,7 +183,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) {
@@ -183,7 +195,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 33fead8..74e53fc 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'];
 
@@ -604,22 +605,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') {
@@ -685,6 +686,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 65e36b7..64d244d 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 5386af67d7be2926e85966e198525e35d5e76b81
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 e227c232fd8067177334be369a584af8497666dc
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 615108f..f7abba4 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 df56b77591d1b4c4bd50dfc83d37f10117817b2e
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 09c8671..615108f 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