Verified Commit bf98f857 authored by Théodore Biadala's avatar Théodore Biadala
Browse files

Issue #3096790 by mrshowerman, danflanagan8, dcam, smustgrave, mgifford, xjm,...

Issue #3096790 by mrshowerman, danflanagan8, dcam, smustgrave, mgifford, xjm, jwilson3, thatguy, swirt, damienmckenna, glugmeister, duaelfr, henry.odiete, paulocs, larowlan, catch, chetanbharambe, ethant, guilhermevp: aria-required attribute is redundant when required attribute is present
parent 44f56c2c
Loading
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -142,7 +142,6 @@ public static function setAttributes(&$element, $class = []) {
    if (!empty($element['#required'])) {
      $element['#attributes']['class'][] = 'required';
      $element['#attributes']['required'] = 'required';
      $element['#attributes']['aria-required'] = 'true';
    }
    if (isset($element['#parents']) && isset($element['#errors']) && !empty($element['#validated'])) {
      $element['#attributes']['class'][] = 'error';
+2 −2
Original line number Diff line number Diff line
@@ -719,7 +719,7 @@
      if (e.value) {
        const label = `label${e.target.id ? `[for=${e.target.id}]` : ''}`;
        const $label = $(e.target)
          .attr({ required: 'required', 'aria-required': 'true' })
          .attr({ required: 'required' })
          .closest('.js-form-item, .js-form-wrapper')
          .find(label);
        // Avoids duplicate required markers on initialization.
@@ -728,7 +728,7 @@
        }
      } else {
        $(e.target)
          .removeAttr('required aria-required')
          .removeAttr('required')
          .closest('.js-form-item, .js-form-wrapper')
          .find('label.js-form-required')
          .removeClass('js-form-required form-required');
+7 −0
Original line number Diff line number Diff line
@@ -169,6 +169,7 @@ protected function doCheckboxTriggerTests(): void {
    $this->assertFalse($details->hasAttribute('open'));
    $this->assertFalse($textfield_in_details->isVisible());
    $this->assertFalse($textfield_required_element->hasAttribute('required'));
    $this->assertFalse($textfield_required_element->hasAttribute('aria-required'));
    $this->assertFalse($textfield_readonly_element->hasAttribute('readonly'));
    $this->assertFalse($textarea_readonly_element->hasAttribute('readonly'));
    $this->assertFalse($checkbox_checked_element->isChecked());
@@ -204,6 +205,7 @@ protected function doCheckboxTriggerTests(): void {
    // Verify triggered state.
    $this->assertFalse($textfield_invisible_element->isVisible());
    $this->assertEquals('required', $textfield_required_element->getAttribute('required'));
    $this->assertFalse($textfield_required_element->hasAttribute('aria-required'));
    $this->assertTrue($textfield_readonly_element->hasAttribute('readonly'));
    $this->assertTrue($textarea_readonly_element->hasAttribute('readonly'));
    $this->assertTrue($details->hasAttribute('open'));
@@ -350,6 +352,7 @@ protected function doTextfieldTriggerTests(): void {
    $this->assertTrue($select_invisible_target->isVisible());
    $this->assertFalse($select_visible_target->isVisible());
    $this->assertFalse($textfield_required_target->hasAttribute('required'));
    $this->assertFalse($textfield_required_target->hasAttribute('aria-required'));
    $this->assertFalse($details->hasAttribute('open'));
    $this->assertFalse($textfield_in_details->isVisible());

@@ -361,6 +364,7 @@ protected function doTextfieldTriggerTests(): void {
    $this->assertFalse($select_invisible_target->isVisible());
    $this->assertTrue($select_visible_target->isVisible());
    $this->assertEquals('required', $textfield_required_target->getAttribute('required'));
    $this->assertFalse($textfield_required_target->hasAttribute('aria-required'));
    $this->assertTrue($details->hasAttribute('open'));
    $this->assertTrue($textfield_in_details->isVisible());
  }
@@ -397,6 +401,7 @@ protected function doRadiosTriggerTests(): void {
    $this->assertTrue($checkbox_unchecked_target->isChecked());
    $this->assertTrue($textfield_invisible_target->isVisible());
    $this->assertFalse($select_required_target->hasAttribute('required'));
    $this->assertFalse($select_required_target->hasAttribute('aria-required'));
    $this->assertFalse($details->hasAttribute('open'));
    $this->assertFalse($textfield_in_details->isVisible());

@@ -407,6 +412,7 @@ protected function doRadiosTriggerTests(): void {
    $this->assertTrue($textfield_in_fieldset->isVisible());
    $this->assertFalse($textfield_invisible_target->isVisible());
    $this->assertTrue($select_required_target->hasAttribute('required'));
    $this->assertFalse($select_required_target->hasAttribute('aria-required'));
    // Checkboxes and details should not have changed state, yet.
    $this->assertFalse($checkbox_checked_target->isChecked());
    $this->assertTrue($checkbox_unchecked_target->isChecked());
@@ -420,6 +426,7 @@ protected function doRadiosTriggerTests(): void {
    // Textfield and select should revert to initial state.
    $this->assertTrue($textfield_invisible_target->isVisible());
    $this->assertFalse($select_required_target->hasAttribute('required'));
    $this->assertFalse($select_required_target->hasAttribute('aria-required'));
    // Checkbox states should now change.
    $this->assertTrue($checkbox_checked_target->isChecked());
    $this->assertFalse($checkbox_unchecked_target->isChecked());
+102 −0
Original line number Diff line number Diff line
@@ -111,4 +111,106 @@ public function testPreRenderAjaxFormWithQueryOptions(): void {
    $this->assertEquals($url, $element['#attached']['drupalSettings']['ajax']['test']['url']);
  }

  /**
   * @covers ::setAttributes
   *
   * @dataProvider providerTestSetAttributes
   */
  public function testSetAttributes(array $element, array $class, array $expected): void {
    RenderElementBase::setAttributes($element, $class);
    $this->assertSame($expected, $element);
  }

  /**
   * Provides test data for testSetAttributes().
   */
  public static function providerTestSetAttributes(): array {
    return [
      'No-op' => [
        'element' => [
          '#type' => 'textfield',
        ],
        'class' => [],
        'expected' => [
          '#type' => 'textfield',
        ],
      ],
      'Add first class' => [
        'element' => [
          '#type' => 'textfield',
        ],
        'class' => ['foo', 'bar'],
        'expected' => [
          '#type' => 'textfield',
          '#attributes' => [
            'class' => [
              'foo',
              'bar',
            ],
          ],
        ],
      ],
      'Append classes' => [
        'element' => [
          '#type' => 'textfield',
          '#attributes' => [
            'class' => [
              'foo',
              'bar',
            ],
          ],
        ],
        'class' => ['baz'],
        'expected' => [
          '#type' => 'textfield',
          '#attributes' => [
            'class' => [
              'foo',
              'bar',
              'baz',
            ],
          ],
        ],
      ],
      'Required' => [
        'element' => [
          '#type' => 'textfield',
          '#required' => TRUE,
        ],
        'class' => [],
        'expected' => [
          '#type' => 'textfield',
          '#required' => TRUE,
          '#attributes' => [
            'class' => [
              'required',
            ],
            'required' => 'required',
          ],
        ],
      ],
      'Parent with error' => [
        'element' => [
          '#type' => 'textfield',
          '#parents' => ['dummy_parent'],
          '#errors' => 'invalid',
          '#validated' => TRUE,
        ],
        'class' => [],
        'expected' => [
          '#type' => 'textfield',
          '#parents' => ['dummy_parent'],
          '#errors' => 'invalid',
          '#validated' => TRUE,
          '#attributes' => [
            'class' => [
              'error',
            ],
            'aria-invalid' => 'true',
          ],
        ],
      ],
    ];
  }

}