Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.975
diff -u -p -r1.975 common.inc
--- includes/common.inc	25 Aug 2009 21:53:47 -0000	1.975
+++ includes/common.inc	26 Aug 2009 05:08:38 -0000
@@ -2963,8 +2963,9 @@ function drupal_add_js($data = NULL, $op
           'preprocess' => TRUE,
         ),
       );
-      // jQuery itself is registered as a library.
+      // Register all required libraries.
       drupal_add_library('system', 'jquery');
+      drupal_add_library('system', 'once');
     }
 
     switch ($options['type']) {
Index: misc/autocomplete.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/autocomplete.js,v
retrieving revision 1.32
diff -u -p -r1.32 autocomplete.js
--- misc/autocomplete.js	17 Aug 2009 07:12:15 -0000	1.32
+++ misc/autocomplete.js	26 Aug 2009 05:08:38 -0000
@@ -7,7 +7,7 @@
 Drupal.behaviors.autocomplete = {
   attach: function (context, settings) {
     var acdb = [];
-    $('input.autocomplete:not(.autocomplete-processed)', context).each(function () {
+    $('input.autocomplete', context).once('autocomplete', function () {
       var uri = this.value;
       if (!acdb[uri]) {
         acdb[uri] = new Drupal.ACDB(uri);
@@ -16,7 +16,6 @@ Drupal.behaviors.autocomplete = {
         .attr('autocomplete', 'OFF')[0];
       $(input.form).submit(Drupal.autocompleteSubmit);
       new Drupal.jsAC(input, acdb[uri]);
-      $(this).addClass('autocomplete-processed');
     });
   }
 };
Index: misc/batch.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/batch.js,v
retrieving revision 1.9
diff -u -p -r1.9 batch.js
--- misc/batch.js	27 Apr 2009 20:19:35 -0000	1.9
+++ misc/batch.js	26 Aug 2009 05:08:38 -0000
@@ -6,11 +6,7 @@
  */
 Drupal.behaviors.batch = {
   attach: function (context, settings) {
-    // This behavior attaches by ID, so is only valid once on a page.
-    if ($('#progress.batch-processed').size()) {
-      return;
-    }
-    $('#progress', context).addClass('batch-processed').each(function () {
+    $('#progress', context).once('batch', function () {
       var holder = $(this);
 
       // Success: redirect to the summary.
Index: misc/collapse.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/collapse.js,v
retrieving revision 1.23
diff -u -p -r1.23 collapse.js
--- misc/collapse.js	27 Apr 2009 20:19:35 -0000	1.23
+++ misc/collapse.js	26 Aug 2009 05:08:38 -0000
@@ -53,7 +53,7 @@ Drupal.collapseScrollIntoView = function
 
 Drupal.behaviors.collapse = {
   attach: function (context, settings) {
-    $('fieldset.collapsible > legend:not(.collapse-processed)', context).each(function () {
+    $('fieldset.collapsible > legend', context).once('collapse', function () {
       var fieldset = $(this.parentNode);
       // Expand if there are errors inside
       if ($('input.error, textarea.error, select.error', fieldset).size() > 0) {
@@ -81,9 +81,10 @@ Drupal.behaviors.collapse = {
           return false;
         }))
         .append(summary)
-        .after($('<div class="fieldset-wrapper"></div>')
-          .append(fieldset.children(':not(legend):not(.action)'))
-        ).addClass('collapse-processed');
+        .after(
+          $('<div class="fieldset-wrapper"></div>')
+            .append(fieldset.children(':not(legend):not(.action)'))
+        );
     });
   }
 };
Index: misc/drupal.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/drupal.js,v
retrieving revision 1.57
diff -u -p -r1.57 drupal.js
--- misc/drupal.js	17 Aug 2009 07:12:15 -0000	1.57
+++ misc/drupal.js	26 Aug 2009 05:13:01 -0000
@@ -12,7 +12,6 @@ if ($ === undefined) {
   };
 }
 
-
 (function ($) {
 
 /**
@@ -38,10 +37,15 @@ if ($ === undefined) {
  * loaded, feeding in an element to be processed, in order to attach all
  * behaviors to the new content.
  *
- * Behaviors should use a class in the form behaviorName-processed to ensure
- * the behavior is attached only once to a given element. (Doing so enables
- * the reprocessing of given elements, which may be needed on occasion despite
- * the ability to limit behavior attachment to a particular element.)
+ * Behaviors should use
+ * @code
+ *   $(selector).once('behavior-name', function () {
+ *     ...
+ *   });
+ * @endcode
+ * to ensure the behavior is attached only once to a given element. (Doing so
+ * enables the reprocessing of given elements, which may be needed on occasion
+ * despite the ability to limit behavior attachment to a particular element.)
  *
  * @param context
  *   An element to attach behaviors to. If none is given, the document element
Index: misc/form.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/form.js,v
retrieving revision 1.10
diff -u -p -r1.10 form.js
--- misc/form.js	25 Aug 2009 13:30:54 -0000	1.10
+++ misc/form.js	26 Aug 2009 05:08:38 -0000
@@ -61,8 +61,7 @@ Drupal.behaviors.formUpdated = {
 Drupal.behaviors.multiselectSelector = {
   attach: function (context, settings) {
     // Automatically selects the right radio button in a multiselect control.
-    $('.multiselect select:not(.multiselectSelector-processed)', context)
-      .addClass('multiselectSelector-processed').change(function () {
+    $('.multiselect select', context).once('multiselect').change(function () {
         $('.multiselect input:radio[value="' + this.id.substr(5) + '"]')
           .attr('checked', true);
     });
@@ -75,8 +74,7 @@ Drupal.behaviors.multiselectSelector = {
  */
 Drupal.behaviors.filterGuidelines = {
   attach: function (context) {
-    $('.filter-guidelines:not(.filter-guidelines-processed)', context)
-      .addClass('filter-guidelines-processed')
+    $('.filter-guidelines', context).once('filter-guidelines')
       .find('label').hide()
       .parents('.filter-wrapper').find('select.filter-list')
       .bind('change', function () {
Index: misc/jquery.once.js
===================================================================
RCS file: misc/jquery.once.js
diff -N misc/jquery.once.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ misc/jquery.once.js	26 Aug 2009 05:08:38 -0000
@@ -0,0 +1,80 @@
+// $Id$
+
+/**
+ * jQuery Once Plugin v1.2
+ * http://plugins.jquery.com/project/once
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ */
+
+(function ($) {
+  var cache = {}, uuid = 0;
+
+  /**
+   * Filters elements by whether they have not yet been processed.
+   *
+   * @param id
+   *   (Optional) If this is a string, then it will be used as the CSS class
+   *   name that is applied to the elements for determining whether it has
+   *   already been processed. The elements will get a class in the form of
+   *   "id-processed".
+   *
+   *   If the id parameter is a function, it will be passed off to the fn
+   *   parameter and the id will become a unique identifier, represented as a
+   *   number.
+   *
+   *   When the id is neither a string or a function, it becomes a unique
+   *   identifier, depicted as a number. The element's class will then be
+   *   represented in the form of "jquery-once-#-processed".
+   *
+   *   Take note that the id must be valid for usage as an element's class name.
+   * @param fn
+   *   (Optional) If given, this function will be called for each element that
+   *   has not yet been processed. The function's return value follows the same
+   *   logic as $.each(). Returning true will continue to the next matched
+   *   element in the set, while returning false will entirely break the
+   *   iteration.
+   */
+  $.fn.once = function (id, fn) {
+    if (typeof id != 'string') {
+      // Generate a numeric ID if the id passed can't be used as a CSS class.
+      if (!(id in cache)) {
+        cache[id] = ++uuid;
+      }
+      // When the fn parameter is not passed, we interpret it from the id.
+      if (!fn) {
+        fn = id;
+      }
+      id = 'jquery-once-' + cache[id];
+    }
+    // Remove elements from the set that have already been processed.
+    var name = id + '-processed';
+    var elements = this.not('.' + name).addClass(name);
+
+    return $.isFunction(fn) ? elements.each(fn) : elements;
+  };
+
+  /**
+   * Filters elements that have been processed once already.
+   *
+   * @param id
+   *   A required string representing the name of the class which should be used
+   *   when filtering the elements. This only filters elements that have already
+   *   been processed by the once function. The id should be the same id that
+   *   was originally passed to the once() function.
+   * @param fn
+   *   (Optional) If given, this function will be called for each element that
+   *   has not yet been processed. The function's return value follows the same
+   *   logic as $.each(). Returning true will continue to the next matched
+   *   element in the set, while returning false will entirely break the
+   *   iteration.
+   */
+  $.fn.removeOnce = function (id, fn) {
+    var name = id + '-processed';
+    var elements = this.filter('.' + name).removeClass(name);
+
+    return $.isFunction(fn) ? elements.each(fn) : elements;
+  };
+})(jQuery);
Index: misc/tabledrag.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/tabledrag.js,v
retrieving revision 1.29
diff -u -p -r1.29 tabledrag.js
--- misc/tabledrag.js	10 Jun 2009 05:06:57 -0000	1.29
+++ misc/tabledrag.js	26 Aug 2009 05:08:38 -0000
@@ -15,17 +15,11 @@
 Drupal.behaviors.tableDrag = {
   attach: function (context, settings) {
     for (var base in settings.tableDrag) {
-      if (!$('#' + base + '.tabledrag-processed', context).size()) {
-        var tableSettings = settings.tableDrag[base];
-
-        $('#' + base).filter(':not(.tabledrag-processed)').each(function () {
-          // Create the new tableDrag instance. Save in the Drupal variable
-          // to allow other scripts access to the object.
-          Drupal.tableDrag[base] = new Drupal.tableDrag(this, tableSettings);
-        });
-
-        $('#' + base).addClass('tabledrag-processed');
-      }
+      $('#' + base, context).once('tabledrag', function () {
+        // Create the new tableDrag instance. Save in the Drupal variable
+        // to allow other scripts access to the object.
+        Drupal.tableDrag[base] = new Drupal.tableDrag(this, settings.tableDrag[base]);
+      });
     }
   }
 };
Index: misc/tableheader.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/tableheader.js,v
retrieving revision 1.24
diff -u -p -r1.24 tableheader.js
--- misc/tableheader.js	27 Apr 2009 20:19:35 -0000	1.24
+++ misc/tableheader.js	26 Aug 2009 05:08:38 -0000
@@ -17,7 +17,7 @@ Drupal.behaviors.tableHeader = {
     // Keep track of all cloned table headers.
     var headers = [];
 
-    $('table.sticky-enabled thead:not(.tableHeader-processed)', context).each(function () {
+    $('table.sticky-enabled thead', context).once('tableheader', function () {
       // Clone thead so it inherits original jQuery properties.
       var headerClone = $(this).clone(true).insertBefore(this.parentNode).wrap('<table class="sticky-header"></table>').parent().css({
         position: 'fixed',
@@ -34,7 +34,6 @@ Drupal.behaviors.tableHeader = {
       tracker(headerClone);
 
       $(table).addClass('sticky-table');
-      $(this).addClass('tableHeader-processed');
     });
 
     // Define the anchor holding var.
@@ -81,11 +80,10 @@ Drupal.behaviors.tableHeader = {
 
     // Only attach to scrollbars once, even if Drupal.attachBehaviors is called
     //  multiple times.
-    if (!$('body').hasClass('tableHeader-processed')) {
-      $('body').addClass('tableHeader-processed');
+    $('body').once(function () {
       $(window).scroll(Drupal.tableHeaderDoScroll);
       $(document.documentElement).scroll(Drupal.tableHeaderDoScroll);
-    }
+    });
 
     // Track scrolling.
     Drupal.tableHeaderOnScroll = function () {
Index: misc/tableselect.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/tableselect.js,v
retrieving revision 1.12
diff -u -p -r1.12 tableselect.js
--- misc/tableselect.js	27 Apr 2009 20:19:35 -0000	1.12
+++ misc/tableselect.js	26 Aug 2009 05:08:38 -0000
@@ -3,7 +3,7 @@
 
 Drupal.behaviors.tableSelect = {
   attach: function (context, settings) {
-    $('form table:has(th.select-all):not(.tableSelect-processed)', context).each(Drupal.tableSelect);
+    $('form table:has(th.select-all)', context).once('table-select', Drupal.tableSelect);
   }
 };
 
@@ -56,7 +56,6 @@ Drupal.tableSelect = function () {
     // Keep track of the last checked checkbox.
     lastChecked = e.target;
   });
-  $(this).addClass('tableSelect-processed');
 };
 
 Drupal.tableSelectRange = function (from, to, state) {
Index: misc/textarea.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/textarea.js,v
retrieving revision 1.29
diff -u -p -r1.29 textarea.js
--- misc/textarea.js	27 Apr 2009 20:19:35 -0000	1.29
+++ misc/textarea.js	26 Aug 2009 05:08:38 -0000
@@ -3,20 +3,16 @@
 
 Drupal.behaviors.textarea = {
   attach: function (context, settings) {
-    $('textarea.resizable:not(.textarea-processed)', context).each(function () {
-      // Avoid non-processed teasers.
-      if ($(this).is(('textarea.teaser:not(.teaser-processed)'))) {
-        return false;
-      }
-      var textarea = $(this).addClass('textarea-processed'), staticOffset = null;
-
+    $('textarea.resizable', context).once('textarea', function () {
       // When wrapping the text area, work around an IE margin bug. See:
       // http://jaspan.com/ie-inherited-margin-bug-form-elements-and-haslayout
-      $(this).wrap('<div class="resizable-textarea"><span></span></div>')
-        .parent().append($('<div class="grippie"></div>').mousedown(startDrag));
-
-      var grippie = $('div.grippie', $(this).parent())[0];
-      grippie.style.marginRight = (grippie.offsetWidth - $(this)[0].offsetWidth) + 'px';
+      var staticOffset = null;
+      var textarea = $(this).wrap('<div class="resizable-textarea"><span></span></div>');
+      var grippie = $('<div class="grippie"></div>').mousedown(startDrag);
+
+      grippie
+        .insertAfter(textarea)
+        .css('margin-right', grippie.width() - textarea.width());
 
       function startDrag(e) {
         staticOffset = textarea.height() - e.pageY;
Index: misc/timezone.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/timezone.js,v
retrieving revision 1.6
diff -u -p -r1.6 timezone.js
--- misc/timezone.js	27 Apr 2009 20:19:35 -0000	1.6
+++ misc/timezone.js	26 Aug 2009 05:08:38 -0000
@@ -6,7 +6,7 @@
  */
 Drupal.behaviors.setTimezone = {
   attach: function (context, settings) {
-    $('select.timezone-detect:not(.timezone-processed)', context).addClass('timezone-processed').each(function () {
+    $('select.timezone-detect', context).once('timezone', function () {
       var dateString = Date();
       // In some client environments, date strings include a time zone
       // abbreviation, between 3 and 5 letters enclosed in parentheses,
Index: misc/vertical-tabs.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/vertical-tabs.js,v
retrieving revision 1.6
diff -u -p -r1.6 vertical-tabs.js
--- misc/vertical-tabs.js	25 Aug 2009 13:30:54 -0000	1.6
+++ misc/vertical-tabs.js	26 Aug 2009 05:08:38 -0000
@@ -15,7 +15,7 @@
  */
 Drupal.behaviors.verticalTabs = {
   attach: function (context) {
-    $('.vertical-tabs-panes:not(.vertical-tabs-processed)', context).each(function () {
+    $('.vertical-tabs-panes', context).once('vertical-tabs', function () {
       var focusID = $(':hidden.vertical-tabs-active-tab', this).val();
       var focus;
       // Create the tab column.
@@ -42,7 +42,7 @@ Drupal.behaviors.verticalTabs = {
         focus = $('> .vertical-tabs-pane:first', this);
       }
       focus.data('verticalTab').focus();
-    }).addClass('vertical-tabs-processed');
+    });
   }
 };
 
Index: modules/block/block.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.js,v
retrieving revision 1.10
diff -u -p -r1.10 block.js
--- modules/block/block.js	4 Aug 2009 06:26:52 -0000	1.10
+++ modules/block/block.js	26 Aug 2009 05:08:38 -0000
@@ -51,7 +51,7 @@ Drupal.behaviors.blockDrag = {
     };
 
     // Add the behavior to each region select list.
-    $('select.block-region-select:not(.blockregionselect-processed)', context).each(function () {
+    $('select.block-region-select', context).once('block-region-select', function () {
       $(this).change(function (event) {
         // Make our new row and select field.
         var row = $(this).parents('tr:first');
@@ -82,7 +82,6 @@ Drupal.behaviors.blockDrag = {
         // Remove focus from selectbox.
         select.get(0).blur();
       });
-      $(this).addClass('blockregionselect-processed');
     });
 
     var checkEmptyRegions = function (table, rowObject) {
Index: modules/color/color.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/color/color.js,v
retrieving revision 1.13
diff -u -p -r1.13 color.js
--- modules/color/color.js	3 Jun 2009 06:50:59 -0000	1.13
+++ modules/color/color.js	26 Aug 2009 05:08:38 -0000
@@ -4,10 +4,10 @@
 Drupal.behaviors.color = {
   attach: function (context, settings) {
     // This behavior attaches by ID, so is only valid once on a page.
-    if ($('#color_scheme_form .color-form.color-processed').size()) {
+    var form = $('#system-theme-settings .color-form', context).once('color');
+    if (form.length == 0) {
       return;
     }
-    var form = $('#system-theme-settings .color-form', context);
     var inputs = [];
     var hooks = [];
     var locks = [];
@@ -24,9 +24,7 @@ Drupal.behaviors.color = {
     }
 
     // Build a preview.
-    $('#preview:not(.color-processed)')
-      .append('<div id="gradient"></div>')
-      .addClass('color-processed');
+    $('#preview').once('color').append('<div id="gradient"></div>');
     var gradient = $('#preview #gradient');
     var h = parseInt(gradient.css('height')) / 10;
     for (i = 0; i < h; ++i) {
Index: modules/comment/comment.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.js,v
retrieving revision 1.11
diff -u -p -r1.11 comment.js
--- modules/comment/comment.js	27 Apr 2009 20:19:36 -0000	1.11
+++ modules/comment/comment.js	26 Aug 2009 05:08:38 -0000
@@ -6,9 +6,7 @@ Drupal.behaviors.comment = {
     $.each(['name', 'homepage', 'mail'], function () {
       var cookie = Drupal.comment.getCookie('comment_info_' + this);
       if (cookie) {
-        $('#comment-form input[name=' + this + ']:not(.comment-processed)', context)
-          .val(cookie)
-          .addClass('comment-processed');
+        $('#comment-form input[name=' + this + ']', context).once('comment').val(cookie);
       }
     });
   }
Index: modules/system/system.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.js,v
retrieving revision 1.33
diff -u -p -r1.33 system.js
--- modules/system/system.js	24 Aug 2009 22:03:01 -0000	1.33
+++ modules/system/system.js	26 Aug 2009 05:12:16 -0000
@@ -32,7 +32,7 @@ Drupal.behaviors.cleanURLsSettingsCheck 
     // This behavior attaches by ID, so is only valid once on a page.
     // Also skip if we are on an install page, as Drupal.cleanURLsInstallCheck will handle
     // the processing.
-    if (!($('#edit-clean-url').size()) || $('.clean-url-processed, #edit-clean-url.install').size()) {
+    if (!($('#edit-clean-url').length) || $('#edit-clean-url.install').once('clean-url').length) {
       return;
     }
     var url = settings.basePath + 'admin/config/search/clean-urls/check';
@@ -44,7 +44,6 @@ Drupal.behaviors.cleanURLsSettingsCheck 
         location = settings.basePath +"admin/config/search/clean-urls";
       }
     });
-    $('#clean-url').addClass('clean-url-processed');
   }
 };
 
@@ -68,7 +67,6 @@ Drupal.cleanURLsInstallCheck = function 
       $('#edit-clean-url').attr('value', 1);
     }
   });
-  $('#edit-clean-url').addClass('clean-url-processed');
 };
 
 /**
@@ -79,21 +77,17 @@ Drupal.cleanURLsInstallCheck = function 
 Drupal.behaviors.copyFieldValue = {
   attach: function (context, settings) {
     for (var sourceId in settings.copyFieldValue) {
-      // Get the list of target fields.
-      targetIds = settings.copyFieldValue[sourceId];
-      if (!$('#'+ sourceId + '.copy-field-values-processed', context).size()) {
+      $('#' + sourceId, context).once('copy-field-values').bind('blur', function () {
+        // Get the list of target fields.
+        var targetIds = settings.copyFieldValue[sourceId];
         // Add the behavior to update target fields on blur of the primary field.
-        sourceField = $('#' + sourceId);
-        sourceField.bind('blur', function () {
-          for (var delta in targetIds) {
-            var targetField = $('#'+ targetIds[delta]);
-            if (targetField.val() == '') {
-              targetField.val(this.value);
-            }
+        for (var delta in targetIds) {
+          var targetField = $('#' + targetIds[delta]);
+          if (targetField.val() == '') {
+            targetField.val(this.value);
           }
-        });
-        sourceField.addClass('copy-field-values-processed');
-      }
+        }
+      });
     }
   }
 };
@@ -104,12 +98,12 @@ Drupal.behaviors.copyFieldValue = {
 Drupal.behaviors.dateTime = {
   attach: function (context, settings) {
     // Show/hide custom format depending on the select's value.
-    $('select.date-format:not(.date-time-processed)', context).change(function () {
-      $(this).addClass('date-time-processed').parents('div.date-container').children('div.custom-container')[$(this).val() == 'custom' ? 'show' : 'hide']();
+    $('select.date-format', context).once('date-time').change(function () {
+      $(this).parents('div.date-container').children('div.custom-container')[$(this).val() == 'custom' ? 'show' : 'hide']();
     });
 
     // Attach keyup handler to custom format inputs.
-    $('input.custom-format:not(.date-time-processed)', context).addClass('date-time-processed').keyup(function () {
+    $('input.custom-format', context).once('date-time').keyup(function () {
       var input = $(this);
       var url = settings.dateTime.lookup + (settings.dateTime.lookup.match(/\?q=/) ? '&format=' : '?format=') + encodeURIComponent(input.val());
       $.getJSON(url, function (data) {
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.775
diff -u -p -r1.775 system.module
--- modules/system/system.module	26 Aug 2009 03:01:06 -0000	1.775
+++ modules/system/system.module	26 Aug 2009 05:08:38 -0000
@@ -933,6 +933,16 @@ function system_library() {
     ),
   );
 
+  // jQuery Once.
+  $libraries['once'] = array(
+    'title' => 'jQuery Once',
+    'website' => 'http://plugins.jquery.com/project/once',
+    'version' => '1.2',
+    'js' => array(
+      'misc/jquery.once.js' => array('weight' => JS_LIBRARY - 19),
+    ),
+  );
+
   // jQuery Form Plugin.
   $libraries['form'] = array(
     'title' => 'jQuery Form Plugin',
Index: modules/toolbar/toolbar.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.js,v
retrieving revision 1.1
diff -u -p -r1.1 toolbar.js
--- modules/toolbar/toolbar.js	4 Jul 2009 05:37:30 -0000	1.1
+++ modules/toolbar/toolbar.js	26 Aug 2009 05:08:38 -0000
@@ -8,18 +8,12 @@ Drupal.behaviors.admin = {
   attach: function() {
 
     // Set the intial state of the toolbar.
-    $('#toolbar:not(.processed)').each(function() {
-      Drupal.admin.toolbar.init();
-      $(this).addClass('processed');
-    });
+    $('#toolbar', context).once('toolbar', Drupal.admin.toolbar.init);
 
     // Toggling of admin shortcuts visibility.
-    $('#toolbar span.toggle:not(.processed)').each(function() {
-      $(this).click(function() {
-        Drupal.admin.toolbar.toggle();
-        return false;
-      });
-      $(this).addClass('processed');
+    $('#toolbar span.toggle', context).once('toolbar-toggle').click(function() {
+      Drupal.admin.toolbar.toggle();
+      return false;
     });
   }
 };
Index: modules/user/user.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.js,v
retrieving revision 1.16
diff -u -p -r1.16 user.js
--- modules/user/user.js	21 Aug 2009 14:27:47 -0000	1.16
+++ modules/user/user.js	26 Aug 2009 05:08:38 -0000
@@ -8,8 +8,8 @@
 Drupal.behaviors.password = {
   attach: function (context, settings) {
     var translate = settings.password;
-    $('input.password-field:not(.password-processed)', context).each(function () {
-      var passwordInput = $(this).addClass('password-processed');
+    $('input.password-field', context).once('password', function () {
+      var passwordInput = $(this);
       var innerWrapper = $(this).parent();
       var outerWrapper = $(this).parent().parent();
 
