diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 6627118..52b2b43 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -514,8 +514,8 @@ function template_preprocess_datetime_wrapper(&$variables) { } $variables['required'] = FALSE; - // For required datetime fields a 'form-required' class is appended to the - // label attributes. + // For required datetime fields a 'form-required' & 'js-form-required' class + // is appended to the label attributes. if (!empty($element['#required'])) { $variables['required'] = TRUE; } @@ -1657,6 +1657,7 @@ function template_preprocess_field_multiple_value_form(&$variables) { $order_class = $element['#field_name'] . '-delta-order'; $header_attributes = new Attribute(array('class' => array('label'))); if (!empty($element['#required'])) { + $header_attributes['class'][] = 'js-form-required'; $header_attributes['class'][] = 'form-required'; } $header = array( diff --git a/core/lib/Drupal/Core/Render/Element/Details.php b/core/lib/Drupal/Core/Render/Element/Details.php index c45810e..cf57bc7 100644 --- a/core/lib/Drupal/Core/Render/Element/Details.php +++ b/core/lib/Drupal/Core/Render/Element/Details.php @@ -54,9 +54,9 @@ public function getInfo() { public static function preRenderDetails($element) { Element::setAttributes($element, array('id')); - // The .form-wrapper class is required for #states to treat details like + // The .js-form-wrapper class is required for #states to treat details like // containers. - static::setAttributes($element, array('form-wrapper')); + static::setAttributes($element, array('js-form-wrapper', 'form-wrapper')); // Collapsible details. $element['#attached']['library'][] = 'core/drupal.collapse'; diff --git a/core/misc/states.js b/core/misc/states.js index 680e86e..c520d7c 100644 --- a/core/misc/states.js +++ b/core/misc/states.js @@ -509,7 +509,7 @@ if (e.trigger) { $(e.target) .prop('disabled', e.value) - .closest('.form-item, .form-submit, .form-wrapper').toggleClass('form-disabled', e.value) + .closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value) .find('select, input, textarea').prop('disabled', e.value); // Note: WebKit nightlies don't reflect that change correctly. @@ -520,21 +520,21 @@ $(document).on('state:required', function (e) { if (e.trigger) { if (e.value) { - var $label = $(e.target).attr({'required': 'required', 'aria-required': 'aria-required'}).closest('.form-item, .form-wrapper').find('label'); + var $label = $(e.target).attr({'required': 'required', 'aria-required': 'aria-required'}).closest('.js-form-item, .js-form-wrapper').find('label'); // Avoids duplicate required markers on initialization. - if (!$label.hasClass('form-required').length) { - $label.addClass('form-required'); + if (!$label.hasClass('js-form-required').length) { + $label.addClass('js-form-required form-required'); } } else { - $(e.target).removeAttr('required aria-required').closest('.form-item, .form-wrapper').find('label.form-required').removeClass('form-required'); + $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required'); } } }); $(document).on('state:visible', function (e) { if (e.trigger) { - $(e.target).closest('.form-item, .form-submit, .form-wrapper').toggle(e.value); + $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value); } }); diff --git a/core/modules/datetime/src/Tests/DateTimeFieldTest.php b/core/modules/datetime/src/Tests/DateTimeFieldTest.php index e2223dc..b7a2988 100644 --- a/core/modules/datetime/src/Tests/DateTimeFieldTest.php +++ b/core/modules/datetime/src/Tests/DateTimeFieldTest.php @@ -100,7 +100,7 @@ function testDateField() { // Display creation form. $this->drupalGet('entity_test/add'); $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.'); - $this->assertFieldByXPath('//*[@id="edit-' . $field_name . '-wrapper"]/h4[contains(@class, "form-required")]', TRUE, 'Required markup found'); + $this->assertFieldByXPath('//*[@id="edit-' . $field_name . '-wrapper"]/h4[contains(@class, "js-form-required")]', TRUE, 'Required markup found'); $this->assertNoFieldByName("{$field_name}[0][value][time]", '', 'Time element not found.'); // Submit a valid date and ensure it is accepted. diff --git a/core/modules/field_ui/field_ui.js b/core/modules/field_ui/field_ui.js index 6394c3e..36b2ebe 100644 --- a/core/modules/field_ui/field_ui.js +++ b/core/modules/field_ui/field_ui.js @@ -19,7 +19,7 @@ '.form-item-label label,' + '.form-item-field-name label,' + '.form-item-existing-storage-label label') - .addClass('form-required'); + .addClass('js-form-required form-required'); var $newFieldType = $form.find('select[name="new_storage_type"]'); var $existingStorageName = $form.find('select[name="existing_storage_name"]'); diff --git a/core/modules/field_ui/src/Form/EntityDisplayFormBase.php b/core/modules/field_ui/src/Form/EntityDisplayFormBase.php index f4e3365..248087d 100644 --- a/core/modules/field_ui/src/Form/EntityDisplayFormBase.php +++ b/core/modules/field_ui/src/Form/EntityDisplayFormBase.php @@ -324,7 +324,7 @@ protected function buildFieldRow(FieldDefinitionInterface $field_definition, arr '#title_display' => 'invisible', '#options' => array_combine($regions, $regions), '#empty_value' => '', - '#attributes' => array('class' => array('field-parent')), + '#attributes' => array('class' => array('js-field-parent')), '#parents' => array('fields', $field_name, 'parent'), ), 'hidden_name' => array( @@ -503,7 +503,7 @@ protected function buildExtraFieldRow($field_id, $extra_field) { '#title_display' => 'invisible', '#options' => array_combine($regions, $regions), '#empty_value' => '', - '#attributes' => array('class' => array('field-parent')), + '#attributes' => array('class' => array('js-field-parent')), '#parents' => array('fields', $field_id, 'parent'), ), 'hidden_name' => array( diff --git a/core/modules/image/src/Tests/ImageFieldValidateTest.php b/core/modules/image/src/Tests/ImageFieldValidateTest.php index e6afc32..f803b4b 100644 --- a/core/modules/image/src/Tests/ImageFieldValidateTest.php +++ b/core/modules/image/src/Tests/ImageFieldValidateTest.php @@ -68,11 +68,11 @@ function testRequiredAttributes() { $this->uploadNodeImage($image, $field_name, 'article'); // Look for form-required for the alt text. - $elements = $this->xpath('//label[@for="edit-' . $field_name . '-0-alt" and @class="form-required"]/following-sibling::input[@id="edit-' . $field_name . '-0-alt"]'); + $elements = $this->xpath('//label[@for="edit-' . $field_name . '-0-alt" and @class="js-form-required form-required"]/following-sibling::input[@id="edit-' . $field_name . '-0-alt"]'); $this->assertTrue(isset($elements[0]),'Required marker is shown for the required alt text.'); - $elements = $this->xpath('//label[@for="edit-' . $field_name . '-0-title" and @class="form-required"]/following-sibling::input[@id="edit-' . $field_name . '-0-title"]'); + $elements = $this->xpath('//label[@for="edit-' . $field_name . '-0-title" and @class="js-form-required form-required"]/following-sibling::input[@id="edit-' . $field_name . '-0-title"]'); $this->assertTrue(isset($elements[0]), 'Required marker is shown for the required title text.'); diff --git a/core/modules/system/src/Tests/Common/RenderTest.php b/core/modules/system/src/Tests/Common/RenderTest.php index b137d19..319d4ab 100644 --- a/core/modules/system/src/Tests/Common/RenderTest.php +++ b/core/modules/system/src/Tests/Common/RenderTest.php @@ -652,9 +652,9 @@ function testDrupalRenderChildrenPostRenderCache() { $dom = Html::load($cached_element['#markup']); $xpath = new \DOMXPath($dom); - $parent = $xpath->query('//details[@class="form-wrapper" and @open="open"]/summary[@role="button" and @aria-expanded and text()="Parent"]')->length; - $child = $xpath->query('//details[@class="form-wrapper" and @open="open"]/div[@class="details-wrapper"]/details[@class="form-wrapper" and @open="open"]/summary[@role="button" and @aria-expanded and text()="Child"]')->length; - $subchild = $xpath->query('//details[@class="form-wrapper" and @open="open"]/div[@class="details-wrapper"]/details[@class="form-wrapper" and @open="open"]/div [@class="details-wrapper" and text()="Subchild"]')->length; + $parent = $xpath->query('//details[@class="js-form-wrapper form-wrapper" and @open="open"]/summary[@role="button" and @aria-expanded and text()="Parent"]')->length; + $child = $xpath->query('//details[@class="js-form-wrapper form-wrapper" and @open="open"]/div[@class="details-wrapper"]/details[@class="js-form-wrapper form-wrapper" and @open="open"]/summary[@role="button" and @aria-expanded and text()="Child"]')->length; + $subchild = $xpath->query('//details[@class="js-form-wrapper form-wrapper" and @open="open"]/div[@class="details-wrapper"]/details[@class="js-form-wrapper form-wrapper" and @open="open"]/div [@class="details-wrapper" and text()="Subchild"]')->length; $this->assertTrue($parent && $child && $subchild, 'The correct data is cached: the stored #markup is not affected by #post_render_cache callbacks.'); // Remove markup because it's compared above in the xpath. @@ -719,9 +719,9 @@ function testDrupalRenderChildrenPostRenderCache() { $dom = Html::load($cached_parent_element['#markup']); $xpath = new \DOMXPath($dom); - $parent = $xpath->query('//details[@class="form-wrapper" and @open="open"]/summary[@role="button" and @aria-expanded and text()="Parent"]')->length; - $child = $xpath->query('//details[@class="form-wrapper" and @open="open"]/div[@class="details-wrapper"]/details[@class="form-wrapper" and @open="open"]/summary[@role="button" and @aria-expanded and text()="Child"]')->length; - $subchild = $xpath->query('//details[@class="form-wrapper" and @open="open"]/div[@class="details-wrapper"]/details[@class="form-wrapper" and @open="open"]/div [@class="details-wrapper" and text()="Subchild"]')->length; + $parent = $xpath->query('//details[@class="js-form-wrapper form-wrapper" and @open="open"]/summary[@role="button" and @aria-expanded and text()="Parent"]')->length; + $child = $xpath->query('//details[@class="js-form-wrapper form-wrapper" and @open="open"]/div[@class="details-wrapper"]/details[@class="js-form-wrapper form-wrapper" and @open="open"]/summary[@role="button" and @aria-expanded and text()="Child"]')->length; + $subchild = $xpath->query('//details[@class="js-form-wrapper form-wrapper" and @open="open"]/div[@class="details-wrapper"]/details[@class="js-form-wrapper form-wrapper" and @open="open"]/div [@class="details-wrapper" and text()="Subchild"]')->length; $this->assertTrue($parent && $child && $subchild, 'The correct data is cached for the parent: the stored #markup is not affected by #post_render_cache callbacks.'); // Remove markup because it's compared above in the xpath. @@ -745,8 +745,8 @@ function testDrupalRenderChildrenPostRenderCache() { $dom = Html::load($cached_child_element['#markup']); $xpath = new \DOMXPath($dom); - $child = $xpath->query('//details[@class="form-wrapper" and @open="open"]/summary[@role="button" and @aria-expanded and text()="Child"]')->length; - $subchild = $xpath->query('//details[@class="form-wrapper" and @open="open"]/div [@class="details-wrapper" and text()="Subchild"]')->length; + $child = $xpath->query('//details[@class="js-form-wrapper form-wrapper" and @open="open"]/summary[@role="button" and @aria-expanded and text()="Child"]')->length; + $subchild = $xpath->query('//details[@class="js-form-wrapper form-wrapper" and @open="open"]/div [@class="details-wrapper" and text()="Subchild"]')->length; $this->assertTrue($child && $subchild, 'The correct data is cached for the child: the stored #markup is not affected by #post_render_cache callbacks.'); // Remove markup because it's compared above in the xpath. diff --git a/core/modules/system/src/Tests/Form/ElementsLabelsTest.php b/core/modules/system/src/Tests/Form/ElementsLabelsTest.php index dbf13d2..c0f21f3 100644 --- a/core/modules/system/src/Tests/Form/ElementsLabelsTest.php +++ b/core/modules/system/src/Tests/Form/ElementsLabelsTest.php @@ -53,16 +53,16 @@ function testFormLabels() { // Exercise various defaults for textboxes and modifications to ensure // appropriate override and correct behavior. - $elements = $this->xpath('//label[@for="edit-form-textfield-test-title-and-required" and @class="form-required"]/following-sibling::input[@id="edit-form-textfield-test-title-and-required"]'); + $elements = $this->xpath('//label[@for="edit-form-textfield-test-title-and-required" and @class="js-form-required form-required"]/following-sibling::input[@id="edit-form-textfield-test-title-and-required"]'); $this->assertTrue(isset($elements[0]), 'Label precedes textfield, with required marker inside label.'); - $elements = $this->xpath('//input[@id="edit-form-textfield-test-no-title-required"]/preceding-sibling::label[@for="edit-form-textfield-test-no-title-required" and @class="form-required"]'); + $elements = $this->xpath('//input[@id="edit-form-textfield-test-no-title-required"]/preceding-sibling::label[@for="edit-form-textfield-test-no-title-required" and @class="js-form-required 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="visually-hidden"]'); $this->assertTrue(isset($elements[0]), 'Label preceding field and label class is visually-hidden.'); - $elements = $this->xpath('//input[@id="edit-form-textfield-test-title"]/preceding-sibling::span[@class="form-required"]'); + $elements = $this->xpath('//input[@id="edit-form-textfield-test-title"]/preceding-sibling::span[@class="js-form-required 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"]'); diff --git a/core/modules/system/src/Tests/Form/FormTest.php b/core/modules/system/src/Tests/Form/FormTest.php index e82002b..c43a527 100644 --- a/core/modules/system/src/Tests/Form/FormTest.php +++ b/core/modules/system/src/Tests/Form/FormTest.php @@ -96,7 +96,7 @@ function testRequiredFields() { $elements['file']['empty_values'] = $empty_strings; // Regular expression to find the expected marker on required elements. - $required_marker_preg = '@<.*?class=".*?form-required.*?">@'; + $required_marker_preg = '@<.*?class=".*?js-form-required.*?">@'; // Go through all the elements and all the empty values for them. foreach ($elements as $type => $data) { foreach ($data['empty_values'] as $key => $empty) { diff --git a/core/modules/system/templates/container.html.twig b/core/modules/system/templates/container.html.twig index 6fb8159..9f91a7f 100644 --- a/core/modules/system/templates/container.html.twig +++ b/core/modules/system/templates/container.html.twig @@ -17,4 +17,4 @@ * @ingroup themeable */ #} -{{ children }} +{{ children }} diff --git a/core/modules/system/templates/datetime-wrapper.html.twig b/core/modules/system/templates/datetime-wrapper.html.twig index 45ba069..62a4b9d 100644 --- a/core/modules/system/templates/datetime-wrapper.html.twig +++ b/core/modules/system/templates/datetime-wrapper.html.twig @@ -17,8 +17,7 @@ #} {% set title_classes = [ - 'label', - required ? 'form-required', + required ? 'js-form-required', ] %} {% if title %} @@ -26,5 +25,5 @@ {% endif %} {{ content }} {% if description %} -
{{ description }}
+
{{ description }}
{% endif %} diff --git a/core/modules/system/templates/fieldset.html.twig b/core/modules/system/templates/fieldset.html.twig index ab6796c..1fbe647 100644 --- a/core/modules/system/templates/fieldset.html.twig +++ b/core/modules/system/templates/fieldset.html.twig @@ -21,24 +21,23 @@ * @ingroup themeable */ #} - + {% set legend_span_classes = [ - 'fieldset-legend', - required ? 'form-required', + required ? 'js-form-required', ] %} {# Always wrap fieldset legends in a SPAN for CSS positioning. #} {{ legend.title }} -
+
{% if prefix %} - {{ prefix }} + {{ prefix }} {% endif %} {{ children }} {% if suffix %} - {{ suffix }} + {{ suffix }} {% endif %} {% if description.content %} {{ description.content }}
diff --git a/core/modules/system/templates/form-element-label.html.twig b/core/modules/system/templates/form-element-label.html.twig index 6ececd9..644b4bd 100644 --- a/core/modules/system/templates/form-element-label.html.twig +++ b/core/modules/system/templates/form-element-label.html.twig @@ -18,7 +18,7 @@ set classes = [ title_display == 'after' ? 'option', title_display == 'invisible' ? 'visually-hidden', - required ? 'form-required', + required ? 'js-form-required', ] %} {% if title is not empty or required -%} diff --git a/core/modules/views/src/Tests/ViewElementTest.php b/core/modules/views/src/Tests/ViewElementTest.php index e9c8105..bd17747 100644 --- a/core/modules/views/src/Tests/ViewElementTest.php +++ b/core/modules/views/src/Tests/ViewElementTest.php @@ -71,7 +71,7 @@ public function testViewElement() { // Test a form. $this->drupalGet('views_test_data_element_form'); - $xpath = $this->xpath('//div[@class="views-element-container form-wrapper"]'); + $xpath = $this->xpath('//div[@class="views-element-container js-form-wrapper form-wrapper"]'); $this->assertTrue($xpath, 'The view container has been found on the form.'); $xpath = $this->xpath('//div[@class="view-content"]'); @@ -138,7 +138,7 @@ public function testViewElementEmbed() { // Test a form. $this->drupalGet('views_test_data_element_embed_form'); - $xpath = $this->xpath('//div[@class="views-element-container form-wrapper"]'); + $xpath = $this->xpath('//div[@class="views-element-container js-form-wrapper form-wrapper"]'); $this->assertTrue($xpath, 'The view container has been found on the form.'); $xpath = $this->xpath('//div[@class="view-content"]'); diff --git a/core/themes/classy/templates/system/container.html.twig b/core/themes/classy/templates/system/container.html.twig index 6fb8159..86c2da2 100644 --- a/core/themes/classy/templates/system/container.html.twig +++ b/core/themes/classy/templates/system/container.html.twig @@ -17,4 +17,4 @@ * @ingroup themeable */ #} -{{ children }}
+{{ children }} diff --git a/core/themes/classy/templates/system/datetime-wrapper.html.twig b/core/themes/classy/templates/system/datetime-wrapper.html.twig index 45ba069..fbf6bb2 100644 --- a/core/themes/classy/templates/system/datetime-wrapper.html.twig +++ b/core/themes/classy/templates/system/datetime-wrapper.html.twig @@ -18,6 +18,7 @@ {% set title_classes = [ 'label', + required ? 'js-form-required', required ? 'form-required', ] %} diff --git a/core/themes/classy/templates/system/fieldset.html.twig b/core/themes/classy/templates/system/fieldset.html.twig index ab6796c..325d341 100644 --- a/core/themes/classy/templates/system/fieldset.html.twig +++ b/core/themes/classy/templates/system/fieldset.html.twig @@ -21,10 +21,11 @@ * @ingroup themeable */ #} - + {% set legend_span_classes = [ 'fieldset-legend', + required ? 'js-form-required', required ? 'form-required', ] %} diff --git a/core/themes/classy/templates/system/form-element-label.html.twig b/core/themes/classy/templates/system/form-element-label.html.twig index 6ececd9..7696609 100644 --- a/core/themes/classy/templates/system/form-element-label.html.twig +++ b/core/themes/classy/templates/system/form-element-label.html.twig @@ -18,6 +18,7 @@ set classes = [ title_display == 'after' ? 'option', title_display == 'invisible' ? 'visually-hidden', + required ? 'js-form-required', required ? 'form-required', ] %}