Make WordPress Core

Changeset 65228


Ignore:
Timestamp:
11/03/2026 02:36:41 PM (9 days ago)
Author:
jonsurrell
Message:

Interactivity API: Remove event handler bind directives.

Server processing now removes data-wp-bind--on* directives from output.

Developed in: ​https://github.com/WordPress/wordpress-develop/pull/15396

Follow-up to r61885.

Props jonsurrell, ntsekouras, luisherranz.
See #66452.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/interactivity-api/class-wp-interactivity-api.php

    r64878 r65228  
    11541154         *              JSON encoder, and a value which cannot be sent to the client is rejected rather than passed to
    11551155         *              WP_HTML_Tag_Processor::set_attribute().
     1156         * @since 7.2.0 Event handler bind directives are removed.
    11561157         *
    11571158         * @param WP_Interactivity_API_Directives_Processor $p    The directives processor instance.
    … …  
    11601161        private function data_wp_bind_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ): void {
    11611162                if ( 'enter' === $mode ) {
    1162                         $entries = $this->get_directive_entries( $p, 'bind' );
     1163                        $event_handler_prefix = 'data-wp-bind--on';
     1164                        $entries              = $this->get_directive_entries( $p, 'bind' );
    11631165                        foreach ( $entries as $entry ) {
     1166                                // Binding event handler attributes is not supported.
     1167                                if ( str_starts_with( $entry['attribute_name'], $event_handler_prefix ) ) {
     1168                                        $p->remove_attribute( $entry['attribute_name'] );
     1169                                        _doing_it_wrong(
     1170                                                __METHOD__,
     1171                                                sprintf(
     1172                                                        /* translators: %s: The directive, e.g. data-wp-on--click. */
     1173                                                        __( 'Binding event handler attributes is not supported. Please use "%s" instead.' ),
     1174                                                        esc_attr( 'data-wp-on--' . substr( $entry['attribute_name'], strlen( $event_handler_prefix ) ) )
     1175                                                ),
     1176                                                '6.9.2'
     1177                                        );
     1178                                        continue;
     1179                                }
     1180
    11641181                                if ( empty( $entry['suffix'] ) || null !== $entry['unique_id'] ) {
    11651182                                        continue;
    … …  
    11801197                                                ),
    11811198                                                '7.1.4'
    1182                                         );
    1183                                         continue;
    1184                                 }
    1185 
    1186                                 // Skip if the suffix is an event handler.
    1187                                 if ( str_starts_with( $entry['suffix'], 'on' ) ) {
    1188                                         _doing_it_wrong(
    1189                                                 __METHOD__,
    1190                                                 sprintf(
    1191                                                         /* translators: %s: The directive, e.g. data-wp-on--click. */
    1192                                                         __( 'Binding event handler attributes is not supported. Please use "%s" instead.' ),
    1193                                                         esc_attr( 'data-wp-on--' . substr( $entry['suffix'], 2 ) )
    1194                                                 ),
    1195                                                 '6.9.2'
    11961199                                        );
    11971200                                        continue;
  • trunk/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-bind.php

    r65006 r65228  
    990990                );
    991991        }
     992
     993        /**
     994         * Data provider for event handler bindings.
     995         *
     996         * @return array<non-empty-string, array{ attribute: non-empty-string }> Data provider.
     997         */
     998        public static function data_event_handler_bindings(): array {
     999                return array(
     1000                        'event handler'                         => array( 'attribute' => 'data-wp-bind--onclick' ),
     1001                        'event handler with an empty unique ID' => array( 'attribute' => 'data-wp-bind--onclick---' ),
     1002                        'event handler with a unique ID'        => array( 'attribute' => 'data-wp-bind--onclick---unique-id' ),
     1003                );
     1004        }
     1005
     1006        /**
     1007         * Tests that `data-wp-bind` removes event handler bindings.
     1008         *
     1009         * @ticket 66452
     1010         *
     1011         * @covers ::process_directives
     1012         *
     1013         * @dataProvider data_event_handler_bindings
     1014         *
     1015         * @expectedIncorrectUsage WP_Interactivity_API::data_wp_bind_processor
     1016         *
     1017         * @param non-empty-string $attribute Directive attribute name.
     1018         */
     1019        public function test_wp_bind_removes_event_handler_bindings( string $attribute ): void {
     1020                $html     = "<button att-before {$attribute}=\"myPlugin::state.id\" att-after>Text</button>";
     1021                $new_html = $this->interactivity->process_directives( $html );
     1022                $this->assertEqualHTML( '<button att-before att-after>Text</button>', $new_html );
     1023        }
     1024
     1025        /**
     1026         * Tests that `data-wp-bind` removes an event handler binding but still
     1027         * processes valid bind directives on the same element.
     1028         *
     1029         * @ticket 66452
     1030         *
     1031         * @covers ::process_directives
     1032         *
     1033         * @expectedIncorrectUsage WP_Interactivity_API::data_wp_bind_processor
     1034         */
     1035        public function test_wp_bind_removes_event_handler_binding_but_processes_valid_binds(): void {
     1036                $html     = '<button data-wp-bind--onclick="myPlugin::state.id" data-wp-bind--id="myPlugin::state.id">Text</button>';
     1037                $new_html = $this->interactivity->process_directives( $html );
     1038                $this->assertEqualHTML( '<button data-wp-bind--id="myPlugin::state.id" id="some-id">Text</button>', $new_html );
     1039        }
    9921040}
Note: See TracChangeset for help on using the changeset viewer.