Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1128
diff -u -p -r1.1128 common.inc
--- includes/common.inc	12 Mar 2010 14:20:32 -0000	1.1128
+++ includes/common.inc	12 Mar 2010 17:35:41 -0000
@@ -4080,6 +4080,7 @@ function drupal_add_tabledrag($table_id,
     // Add the table drag JavaScript to the page before the module JavaScript
     // to ensure that table drag behaviors are registered before any module
     // uses it.
+    drupal_add_js('misc/jquery.cookie.js', array('weight' => JS_DEFAULT - 2));
     drupal_add_js('misc/tabledrag.js', array('weight' => JS_DEFAULT - 1));
     $js_added = TRUE;
   }
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.441
diff -u -p -r1.441 form.inc
--- includes/form.inc	12 Mar 2010 14:38:37 -0000	1.441
+++ includes/form.inc	12 Mar 2010 17:35:43 -0000
@@ -2911,6 +2911,9 @@ function theme_file($variables) {
  *   where a visual label is not needed, such as a table of checkboxes where
  *   the row and column provide the context. The tooltip will include the
  *   title and required marker.
+ * - invisible: Labels are critical for screen readers to enable them to
+ *   properly navigate through forms but can be visually distracting. This
+ *   property hides the label for everyone except screen readers.
  *
  * If the #title property is not set, then the label and any required marker
  * will not be output, regardless of the #title_display or #required values.
@@ -2941,6 +2944,7 @@ function theme_form_element($variables) 
     $class[] = 'form-type-' . strtr($element['#type'], '_', '-');
   }
   if (!empty($element['#name'])) {
+    case 'invisible':
     $class[] = 'form-item-' . strtr($element['#name'], array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
   }
 
@@ -3027,6 +3031,11 @@ function theme_form_required_marker($var
  *   - element: An associative array containing the properties of the element.
  *     Properties used: #required, #title, #id, #value, #description.
  * @return
+  elseif ($element['#title_display'] == 'invisible') {
+    // Show label only to screen readers to avoid disruption in visual flows.
+    $attributes['class'] = 'element-invisible';
+  }
+  
  *   A string representing the form element label.
  *
  * @ingroup themeable
Index: modules/menu/menu.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.admin.inc,v
retrieving revision 1.76
diff -u -p -r1.76 menu.admin.inc
--- modules/menu/menu.admin.inc	23 Feb 2010 10:32:10 -0000	1.76
+++ modules/menu/menu.admin.inc	12 Mar 2010 17:35:44 -0000
@@ -99,13 +99,15 @@ function _menu_overview_tree_form($tree)
         '#type' => 'weight',
         '#delta' => 50,
         '#default_value' => isset($form_state[$mlid]['weight']) ? $form_state[$mlid]['weight'] : $item['weight'],
+        '#title_display' => 'invisible',
+        '#title' => t('Weight for') . ' ' . $item['title'],
       );
       $form[$mlid]['mlid'] = array(
         '#type' => 'hidden',
         '#value' => $item['mlid'],
       );
       $form[$mlid]['plid'] = array(
-        '#type' => 'textfield',
+        '#type' => 'hidden',
         '#default_value' => isset($form_state[$mlid]['plid']) ? $form_state[$mlid]['plid'] : $item['plid'],
         '#size' => 6,
       );
Index: modules/field_ui/field_ui.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui.admin.inc,v
retrieving revision 1.45
diff -u -p -r1.45 field_ui.admin.inc
--- modules/field_ui/field_ui.admin.inc	3 Mar 2010 08:01:42 -0000	1.45
+++ modules/field_ui/field_ui.admin.inc	12 Mar 2010 17:35:44 -0000
@@ -137,7 +137,9 @@ function field_ui_field_overview_form($f
         '#type' => 'textfield',
         '#default_value' => $weight,
         '#size' => 3,
-       ),
+        '#title_display' => 'invisible',
+        '#title' => t('Weight for') . ' ' . check_plain($instance['label']),
+      ),
       'hidden_name' => array(
         '#type' => 'hidden',
         '#default_value' => $instance['field_name'],
Index: modules/block/block.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v
retrieving revision 1.75
diff -u -p -r1.75 block.admin.inc
--- modules/block/block.admin.inc	9 Mar 2010 12:09:52 -0000	1.75
+++ modules/block/block.admin.inc	12 Mar 2010 17:35:44 -0000
@@ -80,6 +80,8 @@ function block_admin_display_form($form,
       '#type' => 'weight',
       '#default_value' => $block['weight'],
       '#delta' => $weight_delta,
+      '#title_display' => 'invisible',
+      '#title' => t('Weight for') . ' ' . check_plain($block['info']),
     );
     $form[$key]['region'] = array(
       '#type' => 'select',
Index: modules/filter/filter.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v
retrieving revision 1.322
diff -u -p -r1.322 filter.module
--- modules/filter/filter.module	8 Mar 2010 03:59:25 -0000	1.322
+++ modules/filter/filter.module	12 Mar 2010 17:35:45 -0000
@@ -1075,7 +1075,7 @@ function theme_filter_tips_more_info() {
 function theme_filter_guidelines($variables) {
   $format = $variables['format'];
 
-  $name = isset($format->name) ? '<label>' . $format->name . ':</label>' : '';
+  $name = isset($format->name) ? $format->name : '';
   return '<div id="filter-guidelines-' . $format->format . '" class="filter-guidelines-item">' . $name . theme('filter_tips', array('tips' => _filter_tips($format->format, FALSE))) . '</div>';
 }
 
Index: modules/simpletest/tests/form.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form.test,v
retrieving revision 1.39
diff -u -p -r1.39 form.test
--- modules/simpletest/tests/form.test	12 Mar 2010 14:38:37 -0000	1.39
+++ modules/simpletest/tests/form.test	12 Mar 2010 17:35:45 -0000
@@ -305,6 +305,9 @@ class FormsElementsLabelsTestCase extend
     $elements = $this->xpath('//input[@id="edit-form-textfield-test-title-after"]/following-sibling::label[@for="edit-form-textfield-test-title-after" and @class="option"]');
     $this->assertTrue(isset($elements[0]), t("Label after field and label option class correct for text field."));
 
+    $elements = $this->xpath('//input[@id="edit-form-textfield-test-title-invisible"]/following-sibling::label[@for="edit-form-textfield-test-title-invisible" and @class="element-invisible"]');
+    $this->assertTrue(isset($elements[0]), t("Label after field and label class is element-invisible."));
+
     $elements = $this->xpath('//label[@for="edit-form-textfield-test-title-no-show"]');
     $this->assertFalse(isset($elements[0]), t("No label tag when title set not to display."));
   }
Index: modules/simpletest/tests/form_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form_test.module,v
retrieving revision 1.30
diff -u -p -r1.30 form_test.module
--- modules/simpletest/tests/form_test.module	7 Mar 2010 07:49:26 -0000	1.30
+++ modules/simpletest/tests/form_test.module	12 Mar 2010 17:35:46 -0000
@@ -536,6 +536,11 @@ function form_label_test_form(&$form_sta
     '#title' => t('Textfield test for title after element'),
     '#title_display' => 'after',
   );
+  $form['form_textfield_test_title_invisible'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Textfield test for invisible title'),
+    '#title_display' => 'invisible',
+  );
   // Textfield test for title set not to display
   $form['form_textfield_test_title_no_show'] = array(
     '#type' => 'textfield',
Index: misc/tabledrag.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/tabledrag.js,v
retrieving revision 1.35
diff -u -p -r1.35 tabledrag.js
--- misc/tabledrag.js	10 Mar 2010 20:31:59 -0000	1.35
+++ misc/tabledrag.js	12 Mar 2010 17:35:46 -0000
@@ -83,8 +83,18 @@ Drupal.tableDrag = function (table, tabl
   // Match immediate children of the parent element to allow nesting.
   $('> tr.draggable, > tbody > tr.draggable', table).each(function() { self.makeDraggable(this); });
 
-  // Hide columns containing affected form elements.
-  this.hideColumns();
+  // Hide or show weight and parent columns according to user preference.
+  // This aids screenreader accessibility so users can enter weight values.
+  // Initialize the weight columns for the show/hide toggle.
+  self.initColumns();
+  // Add a link before the table for users to show or hide weight columns.
+  $(table).before($('<a href="#" class="element-invisible"></a>')
+    .append(Drupal.t('Enable/disable accessible table editing'))
+    .click(function () { 
+      self.toggleShowWeight(self); 
+      return false; 
+    })
+  );
 
   // Add mouse bindings to the document. The self variable is passed along
   // as event handlers do not have direct access to the tableDrag object.
@@ -93,10 +103,12 @@ Drupal.tableDrag = function (table, tabl
 };
 
 /**
- * Hide the columns containing form elements according to the settings for
- * this tableDrag instance.
+ * Initialize weight/parent columns to be hidden by default. 
+ *
+ * Identify and mark each cell with a CSS class so we can easily toggle show/hide it. 
+ * Finally, hide columns if user does not have a 'showWeight' cookie.
  */
-Drupal.tableDrag.prototype.hideColumns = function () {
+Drupal.tableDrag.prototype.initColumns = function () {
   for (var group in this.tableSettings) {
     // Find the first field in this group.
     for (var d in this.tableSettings[group]) {
@@ -108,7 +120,7 @@ Drupal.tableDrag.prototype.hideColumns =
       }
     }
 
-    // Hide the column containing this field.
+    // Mark the column containing this field so it can be hidden.
     if (hidden && cell[0] && cell.css('display') != 'none') {
       // Add 1 to our indexes. The nth-child selector is 1 based, not 0 based.
       // Match immediate children of the parent element to allow nesting.
@@ -128,21 +140,86 @@ Drupal.tableDrag.prototype.hideColumns =
         if (index > 0) {
           cell = row.children(':nth-child(' + index + ')');
           if (cell[0].colSpan > 1) {
-            // If this cell has a colspan, simply reduce it.
-            cell[0].colSpan = cell[0].colSpan - 1;
+            // If this cell has a colspan, mark it so we can reduce the colspan.
+            $(cell[0]).addClass('tabledrag-reduce-colspan');
           }
           else {
-            // Hide table body cells, but remove table header cells entirely
-            // (Safari doesn't hide properly).
-            parentTag == 'thead' ? cell.remove() : cell.css('display', 'none');
+            // Mark this cell so we can hide it.
+            $(cell[0]).addClass('tabledrag-hide');
           }
         }
       });
     }
   }
+
+  // Now hide cells and reduce colspans unless user cookie is set.
+  var show = $.cookie('Drupal.tableDrag.showWeight');
+  if (show != 1) {
+        $.cookie('Drupal.tableDrag.showWeight', 0, {
+        path: Drupal.settings.basePath,
+        // The cookie should "never" expire.
+        expires: 36500,
+      }
+    );
+    Drupal.tableDrag.prototype.hideColumns();
+  }
 };
 
 /**
+ * Hide the columns containing weight/parent form elements.
+ * Undo showColumns().
+ */
+Drupal.tableDrag.prototype.hideColumns = function () {
+  // Turn off display of weight/parent cells and headers.
+  $('.tabledrag-hide').css('display', 'none');
+  // Reduce colspan of any effected multi-span columns.
+  $('.tabledrag-reduce-colspan').each(function() { this.colSpan = this.colSpan - 1; });
+  $('.tabledrag-handle').css('display', 'table-cell');
+
+}
+
+/**
+ * Show the columns containing weight/parent form elements
+ * Undo hideColumns().
+ */
+Drupal.tableDrag.prototype.showColumns = function () {
+  // Increase colspan back to columns it was reduced.
+  $('.tabledrag-reduce-colspan').each(function() { this.colSpan = this.colSpan + 1; });
+  // Turn on display of weight/parent cells and headers.
+  $('.tabledrag-hide').css('display', 'table-cell');
+  $('.tabledrag-handle').css('display', 'none');
+}
+
+/**
+ * Toggle visibility of weight/parent columns. Use a saved cookie to store the
+ * user preference.
+ */
+Drupal.tableDrag.prototype.toggleShowWeight = function (self) {
+  // Retrieve the tableDrag status from a stored cookie.
+  var show = $.cookie('Drupal.tableDrag.showWeight');
+
+  // Show or hide columns with weight fields and toggle the cookie value.
+  if (show == 1) {
+    $.cookie('Drupal.tableDrag.showWeight', 0, {
+        path: Drupal.settings.basePath,
+        // The cookie should "never" expire.
+        expires: 36500,
+      }
+    );
+    this.hideColumns();
+  }
+  else {
+    $.cookie('Drupal.tableDrag.showWeight', 1, {
+        path: Drupal.settings.basePath,
+        // The cookie should "never" expire.
+        expires: 36500,
+      }
+    );
+    this.showColumns();
+  }
+}
+
+/**
  * Find the target used within a particular row and group.
  */
 Drupal.tableDrag.prototype.rowSettings = function (group, row) {
@@ -442,7 +519,7 @@ Drupal.tableDrag.prototype.dropRow = fun
       // fields in the entire dragged group.
       for (var group in self.tableSettings) {
         var rowSettings = self.rowSettings(group, droppedRow);
-        if (rowSettings.relationship == 'group') {
+        if (rowSettings !== undefined && rowSettings.relationship == 'group') {
           for (var n in self.rowObject.children) {
             self.updateField(self.rowObject.children[n], group);
           }
@@ -594,11 +671,11 @@ Drupal.tableDrag.prototype.updateField =
   var rowSettings = this.rowSettings(group, changedRow);
 
   // Set the row as it's own target.
-  if (rowSettings.relationship == 'self' || rowSettings.relationship == 'group') {
+  if (rowSettings !== undefined && (rowSettings.relationship == 'self' || rowSettings.relationship == 'group')) {
     var sourceRow = changedRow;
   }
   // Siblings are easy, check previous and next rows.
-  else if (rowSettings.relationship == 'sibling') {
+  else if (rowSettings !== undefined && rowSettings.relationship == 'sibling') {
     var previousRow = $(changedRow).prev('tr').get(0);
     var nextRow = $(changedRow).next('tr').get(0);
     var sourceRow = changedRow;
@@ -625,7 +702,7 @@ Drupal.tableDrag.prototype.updateField =
   }
   // Parents, look up the tree until we find a field not in this group.
   // Go up as many parents as indentations in the changed row.
-  else if (rowSettings.relationship == 'parent') {
+  else if (rowSettings !== undefined && rowSettings.relationship == 'parent') {
     var previousRow = $(changedRow).prev('tr');
     while (previousRow.length && $('.indentation', previousRow).length >= this.rowObject.indents) {
       previousRow = previousRow.prev('tr');
@@ -659,10 +736,12 @@ Drupal.tableDrag.prototype.updateField =
     rowSettings.relationship = 'sibling';
     rowSettings.source = rowSettings.target;
   }
-
-  var targetClass = '.' + rowSettings.target;
-  var targetElement = $(targetClass, changedRow).get(0);
-
+  
+  if(rowSettings !== undefined) {
+    var targetClass = '.' + rowSettings.target;
+    var targetElement = $(targetClass, changedRow).get(0);
+  }
+  
   // Check if a target element exists in this row.
   if (targetElement) {
     var sourceClass = '.' + rowSettings.source;
