diff --git a/includes/form.inc b/includes/form.inc index e749239..8060224 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -2985,9 +2985,9 @@ function theme_radios($variables) { if (isset($element['#id'])) { $attributes['id'] = $element['#id']; } - $attributes['class'] = 'form-radios'; + $attributes['class'] = array('form-radios'); if (!empty($element['#attributes']['class'])) { - $attributes['class'] .= ' ' . implode(' ', $element['#attributes']['class']); + $attributes['class'] = array_merge($attributes['class'], $element['#attributes']['class']); } if (isset($element['#attributes']['title'])) { $attributes['title'] = $element['#attributes']['title']; @@ -4209,7 +4209,7 @@ function theme_form_element($variables) { // This function is invoked as theme wrapper, but the rendered form element // may not necessarily have been processed by form_builder(). $element += array( - '#title_display' => 'before', + '#title_classes_array' => array(), ); // Add element #id for #type 'item'. @@ -4228,8 +4228,17 @@ function theme_form_element($variables) { if (!empty($element['#attributes']['disabled'])) { $attributes['class'][] = 'form-disabled'; } + // Add classes specified in the element's #attributes. + if (!empty($element['#attributes']['class'])) { + $attributes['class'] = array_merge($attributes['class'], $element['#attributes']['class']); + } $output = '' . "\n"; + // Prevent form field class inheriting to label in theme_form_element_label() + // and allow custom label classes. + $variables_title = $variables; + $variables_title['element']['#attributes']['class'] = $element['#title_classes_array']; + // If #title is not set, we don't display any label or required marker. if (!isset($element['#title'])) { $element['#title_display'] = 'none'; @@ -4240,13 +4249,13 @@ function theme_form_element($variables) { switch ($element['#title_display']) { case 'before': case 'invisible': - $output .= ' ' . theme('form_element_label', $variables); + $output .= ' ' . theme('form_element_label', $variables_title); $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n"; break; case 'after': $output .= ' ' . $prefix . $element['#children'] . $suffix; - $output .= ' ' . theme('form_element_label', $variables) . "\n"; + $output .= ' ' . theme('form_element_label', $variables_title) . "\n"; break; case 'none': @@ -4322,19 +4331,23 @@ function theme_form_element_label($variables) { $title = filter_xss_admin($element['#title']); - $attributes = array(); + $attributes = array('class' => array('form-label')); // Style the label as class option to display inline with the element. if ($element['#title_display'] == 'after') { - $attributes['class'] = 'option'; + $attributes['class'][] = 'option'; } // Show label only to screen readers to avoid disruption in visual flows. elseif ($element['#title_display'] == 'invisible') { - $attributes['class'] = 'element-invisible'; + $attributes['class'][] = 'element-invisible'; } if (!empty($element['#id'])) { $attributes['for'] = $element['#id']; } + // Add classes specified in the element's #attributes. + if (!empty($element['#attributes']['class'])) { + $attributes['class'] = array_merge($attributes['class'], $element['#attributes']['class']); + } // The leading whitespace helps visually separate fields from inline labels. return ' ' . $t('!title !required', array('!title' => $title, '!required' => $required)) . "\n"; diff --git a/modules/simpletest/tests/form.test b/modules/simpletest/tests/form.test index a441cee..50c3286 100644 --- a/modules/simpletest/tests/form.test +++ b/modules/simpletest/tests/form.test @@ -778,23 +778,23 @@ class FormsElementsLabelsTestCase extends DrupalWebTestCase { // Check that the checkbox/radio processing is not interfering with // basic placement. - $elements = $this->xpath('//input[@id="edit-form-checkboxes-test-third-checkbox"]/following-sibling::label[@for="edit-form-checkboxes-test-third-checkbox" and @class="option"]'); + $elements = $this->xpath('//input[@id="edit-form-checkboxes-test-third-checkbox"]/following-sibling::label[@for="edit-form-checkboxes-test-third-checkbox" and contains(@class, "option")]'); $this->assertTrue(isset($elements[0]), "Label follows field and label option class correct for regular checkboxes."); // Make sure the label is rendered for checkboxes. - $elements = $this->xpath('//input[@id="edit-form-checkboxes-test-0"]/following-sibling::label[@for="edit-form-checkboxes-test-0" and @class="option"]'); + $elements = $this->xpath('//input[@id="edit-form-checkboxes-test-0"]/following-sibling::label[@for="edit-form-checkboxes-test-0" and contains(@class, "option")]'); $this->assertTrue(isset($elements[0]), "Label 0 found checkbox."); - $elements = $this->xpath('//input[@id="edit-form-radios-test-second-radio"]/following-sibling::label[@for="edit-form-radios-test-second-radio" and @class="option"]'); + $elements = $this->xpath('//input[@id="edit-form-radios-test-second-radio"]/following-sibling::label[@for="edit-form-radios-test-second-radio" and contains(@class, "option")]'); $this->assertTrue(isset($elements[0]), "Label follows field and label option class correct for regular radios."); // Make sure the label is rendered for radios. - $elements = $this->xpath('//input[@id="edit-form-radios-test-0"]/following-sibling::label[@for="edit-form-radios-test-0" and @class="option"]'); + $elements = $this->xpath('//input[@id="edit-form-radios-test-0"]/following-sibling::label[@for="edit-form-radios-test-0" and contains(@class, "option")]'); $this->assertTrue(isset($elements[0]), "Label 0 found radios."); // Exercise various defaults for checkboxes and modifications to ensure // appropriate override and correct behavior. - $elements = $this->xpath('//input[@id="edit-form-checkbox-test"]/following-sibling::label[@for="edit-form-checkbox-test" and @class="option"]'); + $elements = $this->xpath('//input[@id="edit-form-checkbox-test"]/following-sibling::label[@for="edit-form-checkbox-test" and contains(@class, "option")]'); $this->assertTrue(isset($elements[0]), "Label follows field and label option class correct for a checkbox by default."); // Exercise various defaults for textboxes and modifications to ensure @@ -805,13 +805,13 @@ class FormsElementsLabelsTestCase extends DrupalWebTestCase { $elements = $this->xpath('//input[@id="edit-form-textfield-test-no-title-required"]/preceding-sibling::label[@for="edit-form-textfield-test-no-title-required"]/span[@class="form-required"]'); $this->assertTrue(isset($elements[0]), "Label tag with required marker precedes required textfield with no title."); - $elements = $this->xpath('//input[@id="edit-form-textfield-test-title-invisible"]/preceding-sibling::label[@for="edit-form-textfield-test-title-invisible" and @class="element-invisible"]'); + $elements = $this->xpath('//input[@id="edit-form-textfield-test-title-invisible"]/preceding-sibling::label[@for="edit-form-textfield-test-title-invisible" and contains(@class, "element-invisible")]'); $this->assertTrue(isset($elements[0]), "Label preceding field and label class is element-invisible."); $elements = $this->xpath('//input[@id="edit-form-textfield-test-title"]/preceding-sibling::span[@class="form-required"]'); $this->assertFalse(isset($elements[0]), "No required marker on non-required field."); - $elements = $this->xpath('//input[@id="edit-form-textfield-test-title-after"]/following-sibling::label[@for="edit-form-textfield-test-title-after" and @class="option"]'); + $elements = $this->xpath('//input[@id="edit-form-textfield-test-title-after"]/following-sibling::label[@for="edit-form-textfield-test-title-after" and contains(@class, "option")]'); $this->assertTrue(isset($elements[0]), "Label after field and label option class correct for text field."); $elements = $this->xpath('//label[@for="edit-form-textfield-test-title-no-show"]'); diff --git a/modules/user/user-rtl.css b/modules/user/user-rtl.css index 642c943..cdc6df2 100644 --- a/modules/user/user-rtl.css +++ b/modules/user/user-rtl.css @@ -19,7 +19,7 @@ .password-strength-text { float: left; } -div.password-confirm { +div.password-confirm-title { float: left; } .confirm-parent, diff --git a/modules/user/user.css b/modules/user/user.css index 079ec38..70f20aa 100644 --- a/modules/user/user.css +++ b/modules/user/user.css @@ -56,7 +56,7 @@ input.password-field { width: 16em; margin-bottom: 0.4em; } -div.password-confirm { +div.password-confirm-title { float: right; /* LTR */ margin-top: 1.5em; visibility: hidden; diff --git a/modules/user/user.js b/modules/user/user.js index 4cf9816..5ec5e35 100644 --- a/modules/user/user.js +++ b/modules/user/user.js @@ -16,9 +16,9 @@ Drupal.behaviors.password = { innerWrapper.addClass('password-parent'); // Add the password confirmation layer. - $('input.password-confirm', outerWrapper).parent().prepend('
' + translate['confirmTitle'] + '
').addClass('confirm-parent'); + $('input.password-confirm', outerWrapper).parent().prepend('
' + translate['confirmTitle'] + '
').addClass('confirm-parent'); var confirmInput = $('input.password-confirm', outerWrapper); - var confirmResult = $('div.password-confirm', outerWrapper); + var confirmResult = $('div.password-confirm-title', outerWrapper); var confirmChild = $('span', confirmResult); // Add the description box.