? .settings
Index: includes/ajax.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/ajax.inc,v
retrieving revision 1.31
diff -u -p -r1.31 ajax.inc
--- includes/ajax.inc	30 Apr 2010 08:07:54 -0000	1.31
+++ includes/ajax.inc	4 Jun 2010 20:13:56 -0000
@@ -848,7 +848,7 @@ function ajax_command_changed($selector,
  * The 'css' command will instruct the client to use the jQuery css() method
  * to apply the CSS arguments to elements matched by the given selector.
  *
- * This command is implemented by Drupal.ajax.prototype.commands.insert()
+ * This command is implemented by Drupal.ajax.prototype.commands.css()
  * defined in misc/ajax.js.
  *
  * @param $selector
@@ -871,6 +871,94 @@ function ajax_command_css($selector, $ar
 }
 
 /**
+ * Creates a Drupal AJAX 'attr' command.
+ *
+ * The 'attr' command will instruct the client to use the jQuery attr() method
+ * to set attributes to elements matched by the given selector.
+ *
+ * This command is implemented by Drupal.ajax.prototype.commands.attr()
+ * defined in misc/ajax.js.
+ *
+ * @param $selector
+ *   A jQuery selector string. If the command is a response to a request from
+ *   an #ajax form element then this value can be NULL.
+ * @param $argument
+ *   An array of key/value pairs to set as attributes to elements matching the
+ *   selector.
+ *
+ * @return
+ *   An array suitable for use with the ajax_render() function.
+ *
+ * @see http://api.jquery.com/attr/#attr2
+ */
+function ajax_command_attr($selector, $argument) {
+  return array(
+    'command' => 'attr',
+    'selector' => $selector,
+    'argument' => $argument,
+  );
+}
+
+/**
+ * Creates a Drupal AJAX 'add_class' command.
+ *
+ * The 'add_class' command will instruct the client to use the jQuery
+ * addClass() method to add a class to elements matched by the given selector.
+ *
+ * This command is implemented by Drupal.ajax.prototype.commands.addClass()
+ * defined in misc/ajax.js.
+ *
+ * @param $selector
+ *   A jQuery selector string. If the command is a response to a request from
+ *   an #ajax form element then this value can be NULL.
+ * @param $class
+ *   One or more class names (separated by white spaces) to be added to the
+ *   class attributes of elements matching the selector.
+ *
+ * @return
+ *   An array suitable for use with the ajax_render() function.
+ *
+ * @see http://api.jquery.com/addClass
+ */
+function ajax_command_add_class($selector, $argument) {
+  return array(
+    'command' => 'addClass',
+    'selector' => $selector,
+    'argument' => $argument,
+  );
+}
+
+/**
+ * Creates a Drupal AJAX 'remove_class' command.
+ *
+ * The 'remove_class' command will instruct the client to use the jQuery
+ * removeClass() method to remove a class from elements matched by the given
+ * selector.
+ *
+ * This command is implemented by Drupal.ajax.prototype.commands.removeClass()
+ * defined in misc/ajax.js.
+ *
+ * @param $selector
+ *   A jQuery selector string. If the command is a response to a request from
+ *   an #ajax form element then this value can be NULL.
+ * @param $class
+ *   One or more class names (separated by white spaces) to be removed from the
+ *   class attributes of elements matching the selector.
+ *
+ * @return
+ *   An array suitable for use with the ajax_render() function.
+ *
+ * @see http://api.jquery.com/addClass
+ */
+function ajax_command_remove_class($selector, $argument) {
+  return array(
+    'command' => 'removeClass',
+    'selector' => $selector,
+    'argument' => $argument,
+  );
+}
+
+/**
  * Creates a Drupal AJAX 'settings' command.
  *
  * The 'settings' command instructs the client either to use the given array as
Index: misc/ajax.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/ajax.js,v
retrieving revision 1.17
diff -u -p -r1.17 ajax.js
--- misc/ajax.js	16 May 2010 19:08:08 -0000	1.17
+++ misc/ajax.js	4 Jun 2010 20:33:38 -0000
@@ -405,6 +405,27 @@ Drupal.ajax.prototype.commands = {
   },
 
   /**
+   * Command to provide the jQuery attr() function.
+   */
+  attr: function (ajax, response, status) {
+    $(response.selector).attr(response.argument);
+  },
+
+  /**
+   * Command to provide the jQuery addClass() function.
+   */
+  addClass: function (ajax, response, status) {
+    $(response.selector).addClass(response.argument);
+  },
+
+  /**
+   * Command to provide the jQuery removeClass() function.
+   */
+  removeClass: function (ajax, response, status) {
+    $(response.selector).removeClass(response.argument);
+  },
+
+  /**
    * Command to set the settings that will be used for other commands in this response.
    */
   settings: function (ajax, response, status) {
Index: modules/simpletest/tests/ajax.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/ajax.test,v
retrieving revision 1.11
diff -u -p -r1.11 ajax.test
--- modules/simpletest/tests/ajax.test	30 Apr 2010 08:07:55 -0000	1.11
+++ modules/simpletest/tests/ajax.test	4 Jun 2010 20:25:00 -0000
@@ -132,10 +132,25 @@ class AJAXCommandsTestCase extends AJAXT
     $this->assertTrue($command['command'] == 'changed' && $command['selector'] == '#changed_div' && $command['asterisk'] == '#changed_div_mark_this', "'changed' AJAX command (with asterisk) issued with correct selector");
 
     // Tests the 'css' command.
-    $commands = $this->discardSettings($this->drupalPostAJAX($form_path, $edit, array('op' => t("Set the the '#box' div to be blue."))));
+    $commands = $this->discardSettings($this->drupalPostAJAX($form_path, $edit, array('op' => t("Set the '#box' div to be blue."))));
     $command = $commands[0];
     $this->assertTrue($command['command'] == 'css' && $command['selector'] == '#css_div' && $command['argument']['background-color'] == 'blue', "'css' AJAX command issued with correct selector");
 
+    // Tests the 'attr' command.
+    $commands = $this->discardSettings($this->drupalPostAJAX($form_path, $edit, array('op' => t("Sets a 'foo' attribute to the '#attr-div' div."))));
+    $command = $commands[0];
+    $this->assertTrue($command['command'] == 'attr' && $command['selector'] == '#attr-div', "'attr' AJAX command issued with correct selector");
+
+    // Tests the 'add_class' command.
+    $commands = $this->discardSettings($this->drupalPostAJAX($form_path, $edit, array('op' =>  t("Adds the 'some-class' class to the '#add-class-class' div."))));
+    $command = $commands[0];
+    $this->assertTrue($command['command'] == 'addClass' && $command['selector'] == '#add-class-div', "'add_class' AJAX command issued with correct selector");
+
+    // Tests the 'remove_class' command.
+    $commands = $this->discardSettings($this->drupalPostAJAX($form_path, $edit, array('op' =>  t("Removes the 'some-class' class to the '#remove-class-div' div."))));
+    $command = $commands[0];
+    $this->assertTrue($command['command'] == 'removeClass' && $command['selector'] == '#remove-class-div', "'remove_class' AJAX command issued with correct selector");
+
     // Tests the 'data' command.
     $commands = $this->discardSettings($this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX data command: Issue command."))));
     $command = $commands[0];
Index: modules/simpletest/tests/ajax_forms_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/ajax_forms_test.module,v
retrieving revision 1.7
diff -u -p -r1.7 ajax_forms_test.module
--- modules/simpletest/tests/ajax_forms_test.module	6 May 2010 05:59:31 -0000	1.7
+++ modules/simpletest/tests/ajax_forms_test.module	4 Jun 2010 20:28:41 -0000
@@ -156,7 +156,7 @@ function ajax_forms_test_ajax_commands_f
 
   // Shows the AJAX 'css' command.
   $form['css_command_example'] = array(
-    '#value' => t("Set the the '#box' div to be blue."),
+    '#value' => t("Set the '#box' div to be blue."),
     '#type' => 'submit',
     '#ajax' => array(
       'callback' => 'ajax_forms_test_advanced_commands_css_callback',
@@ -164,6 +164,36 @@ function ajax_forms_test_ajax_commands_f
     '#suffix' => '<div id="css_div" style="height: 50px; width: 50px; border: 1px solid black"> box</div>',
   );
 
+  // Shows the AJAX 'attr' command.
+  $form['attr_command_example'] = array(
+    '#value' => t("Sets a 'foo' attribute to the '#attr-div' div."),
+    '#type' => 'submit',
+    '#ajax' => array(
+      'callback' => 'ajax_forms_test_advanced_commands_attr_callback',
+    ),
+    '#suffix' => '<div id="attr-div"> box</div>',
+  );
+
+  // Shows the AJAX 'add_class' command.
+  $form['add_class_command_example'] = array(
+    '#value' => t("Adds the 'some-class' class to the '#add-class-class' div."),
+    '#type' => 'submit',
+    '#ajax' => array(
+      'callback' => 'ajax_forms_test_advanced_commands_add_class_callback',
+    ),
+    '#suffix' => '<div id="add-class-div"> box</div>',
+  );
+
+  // Shows the AJAX 'remove_class' command.
+  $form['remove_class_command_example'] = array(
+    '#value' => t("Removes the 'some-class' class to the '#remove-class-div' div."),
+    '#type' => 'submit',
+    '#ajax' => array(
+      'callback' => 'ajax_forms_test_advanced_commands_remove_class_callback',
+    ),
+    '#suffix' => '<div id="remove-class-div" class="some-class some_other-class"> box</div>',
+  );
+
 
   // Shows the AJAX 'data' command. But there is no use of this information,
   // as this would require a javascript client to use the data.
@@ -312,6 +342,42 @@ function ajax_forms_test_advanced_comman
 }
 
 /**
+ * AJAX callback for 'attr'.
+ */
+function ajax_forms_test_advanced_commands_attr_callback($form, $form_state) {
+  $selector = '#attr-div';
+  $value = 'bar';
+
+  $commands = array();
+  $commands[] = ajax_command_attr($selector, array('foo' => $value));
+  return array('#type' => 'ajax', '#commands' => $commands);
+}
+
+/**
+ * AJAX callback for 'add_class'.
+ */
+function ajax_forms_test_advanced_commands_add_class_callback($form, $form_state) {
+  $selector = '#add-class-div';
+  $class = 'some-class';
+
+  $commands = array();
+  $commands[] = ajax_command_add_class($selector, $class);
+  return array('#type' => 'ajax', '#commands' => $commands);
+}
+
+/**
+ * AJAX callback for 'remove_class'.
+ */
+function ajax_forms_test_advanced_commands_remove_class_callback($form, $form_state) {
+  $selector = '#remove-class-div';
+  $class = 'some-class';
+
+  $commands = array();
+  $commands[] = ajax_command_remove_class($selector, $class);
+  return array('#type' => 'ajax', '#commands' => $commands);
+}
+
+/**
  * AJAX callback for 'data'.
  */
 function ajax_forms_test_advanced_commands_data_callback($form, $form_state) {
@@ -367,8 +433,6 @@ function ajax_forms_test_advanced_comman
   return array('#type' => 'ajax', '#commands' => $commands);
 }
 
-
-
 /**
  * This form and its related submit and callback functions demonstrate
  * not validating another form element when a single AJAX element is triggered.
