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 '
\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.