Make WordPress Core

Changeset 60304


Ignore:
Timestamp:
06/12/2025 08:45:40 PM (2 weeks ago)
Author:
westonruter
Message:

Comments: Remove novalidate attribute from comments form by default.

Browser support for client-side validation is now reliable. Blocking the form submission when there is a missing/invalid field prevents the possibility of losing comment content when bfcache does not restore the previous page when going back.

To retain the novalidate attribute, the comment_form()'s args now accepts a novalidate key which will add the attribute when it is true. This can also be supplied by the comment_form_default_fields filter, for example:

add_filter( 'comment_form_defaults', function ( $args ) {
    $args['novalidate'] = true;
    return $args;
} );

Fixes #47595.
Props westonruter, joedolson, sabernhardt, afercia, SergeyBiryukov, guddu1315, pfefferle, oglekler, bugnumber9.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/comment-template.php

    r60249 r60304  
    24472447 * @since 4.9.6 Introduced the 'cookies' default comment field.
    24482448 * @since 5.5.0 Introduced the 'class_container' argument.
     2449 * @since 6.8.2 Introduced the 'novalidate' argument.
    24492450 *
    24502451 * @param array       $args {
     
    24682469 *     @type string $comment_notes_after  HTML element for a message displayed after the textarea field.
    24692470 *     @type string $action               The comment form element action attribute. Default '/wp-comments-post.php'.
     2471 *     @type bool   $novalidate           Whether the novalidate attribute is added to the comment form. Default false.
    24702472 *     @type string $id_form              The comment form element id attribute. Default 'commentform'.
    24712473 *     @type string $id_submit            The comment submit element id attribute. Default 'submit'.
     
    26472649        'comment_notes_after'  => '',
    26482650        'action'               => site_url( '/wp-comments-post.php' ),
     2651        'novalidate'           => false,
    26492652        'id_form'              => 'commentform',
    26502653        'id_submit'            => 'submit',
     
    27302733                esc_attr( $args['id_form'] ),
    27312734                esc_attr( $args['class_form'] ),
    2732                 ( $html5 ? ' novalidate' : '' )
     2735                ( $args['novalidate'] ? ' novalidate' : '' )
    27332736            );
    27342737
  • trunk/tests/phpunit/tests/comment/commentForm.php

    r56971 r60304  
    194194        $this->assertStringContainsString( $post_hidden_field, $form );
    195195    }
     196
     197    /**
     198     * Tests novalidate attribute on the comment form.
     199     *
     200     * @ticket 47595
     201     */
     202    public function test_comment_form_and_novalidate_attribute() {
     203        $post_id = self::$post_id;
     204
     205        // By default, the novalidate is not emitted.
     206        $form = get_echo( 'comment_form', array( array(), $post_id ) );
     207        $p    = new WP_HTML_Tag_Processor( $form );
     208        $this->assertTrue( $p->next_tag( array( 'tag_name' => 'FORM' ) ), 'Expected FORM tag.' );
     209        $this->assertNull( $p->get_attribute( 'novalidate' ), 'Expected FORM to not have novalidate attribute by default.' );
     210
     211        // Opt in to the novalidate attribute by passing an arg to comment_form().
     212        $form = get_echo( 'comment_form', array( array( 'novalidate' => true ), $post_id ) );
     213        $p    = new WP_HTML_Tag_Processor( $form );
     214        $this->assertTrue( $p->next_tag( array( 'tag_name' => 'FORM' ) ), 'Expected FORM tag.' );
     215        $this->assertTrue( $p->get_attribute( 'novalidate' ), 'Expected FORM to have the novalidate attribute.' );
     216
     217        // Opt in to the novalidate attribute via the comment_form_defaults filter.
     218        add_filter(
     219            'comment_form_defaults',
     220            static function ( array $defaults ): array {
     221                $defaults['novalidate'] = true;
     222                return $defaults;
     223            }
     224        );
     225        $form = get_echo( 'comment_form', array( array(), $post_id ) );
     226        $p    = new WP_HTML_Tag_Processor( $form );
     227        $this->assertTrue( $p->next_tag( array( 'tag_name' => 'FORM' ) ), 'Expected FORM tag.' );
     228        $this->assertTrue( $p->get_attribute( 'novalidate' ), 'Expected FORM to have novalidate attribute.' );
     229    }
    196230}
Note: See TracChangeset for help on using the changeset viewer.