Make WordPress Core


Ignore:
Timestamp:
11/27/2024 02:33:46 PM (15 months ago)
Author:
Bernhard Reiter
Message:

HTML API: Allow more contexts in create_fragment.

This changeset modifies WP_HTML_Processor::create_fragment( $html, $context ) to use a full processor and create_fragment_at_node instead of the other way around. This makes more sense and makes the main factory methods more clear, where the state required for fragments is set up in create_fragment_at_node instead of in both create_fragment and create_fragment_at_current_node.

This allows for more HTML contexts to be provided to the basic create_fragment where the provided context HTML is appended to <!DOCTYPE html>, a full processor is created, the last tag opener is found, and a fragment parser is created at that node via create_fragment_at_current_node.

The HTML5lib tests are updated accordingly to use this new method to create fragments.

Props jonsurrell, dmsnell, bernhard-reiter.
Fixes #62584.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/html-api/wpHtmlProcessorHtml5lib.php

    r59444 r59467  
    154154     */
    155155    private static function build_tree_representation( ?string $fragment_context, string $html ) {
    156         $processor = null;
    157156        if ( $fragment_context ) {
    158             if ( 'body' === $fragment_context ) {
    159                 $processor = WP_HTML_Processor::create_fragment( $html );
     157            /*
     158             * If the string of characters starts with "svg ", the context
     159             * element is in the SVG namespace and the substring after
     160             * "svg " is the local name. If the string of characters starts
     161             * with "math ", the context element is in the MathML namespace
     162             * and the substring after "math " is the local name.
     163             * Otherwise, the context element is in the HTML namespace and
     164             * the string is the local name.
     165             */
     166            if ( str_starts_with( $fragment_context, 'svg ' ) ) {
     167                $tag_name = substr( $fragment_context, 4 );
     168                if ( 'svg' === $tag_name ) {
     169                    $fragment_context_html = '<svg>';
     170                } else {
     171                    $fragment_context_html = "<svg><{$tag_name}>";
     172                }
     173            } elseif ( str_starts_with( $fragment_context, 'math ' ) ) {
     174                $tag_name = substr( $fragment_context, 5 );
     175                if ( 'math' === $tag_name ) {
     176                    $fragment_context_html = '<math>';
     177                } else {
     178                    $fragment_context_html = "<math><{$tag_name}>";
     179                }
    160180            } else {
    161 
    162                 /*
    163                  * If the string of characters starts with "svg ", the context
    164                  * element is in the SVG namespace and the substring after
    165                  * "svg " is the local name. If the string of characters starts
    166                  * with "math ", the context element is in the MathML namespace
    167                  * and the substring after "math " is the local name.
    168                  * Otherwise, the context element is in the HTML namespace and
    169                  * the string is the local name.
    170                  */
    171                 if ( str_starts_with( $fragment_context, 'svg ' ) ) {
    172                     $tag_name = substr( $fragment_context, 4 );
    173                     if ( 'svg' === $tag_name ) {
    174                         $parent_processor = WP_HTML_Processor::create_full_parser( '<!DOCTYPE html><svg>' );
    175                     } else {
    176                         $parent_processor = WP_HTML_Processor::create_full_parser( "<!DOCTYPE html><svg><{$tag_name}>" );
    177                     }
    178                     $parent_processor->next_tag( $tag_name );
    179                 } elseif ( str_starts_with( $fragment_context, 'math ' ) ) {
    180                     $tag_name = substr( $fragment_context, 5 );
    181                     if ( 'math' === $tag_name ) {
    182                         $parent_processor = WP_HTML_Processor::create_full_parser( '<!DOCTYPE html><math>' );
    183                     } else {
    184                         $parent_processor = WP_HTML_Processor::create_full_parser( "<!DOCTYPE html><math><{$tag_name}>" );
    185                     }
    186                     $parent_processor->next_tag( $tag_name );
     181                // Tags that only appear in tables need a special case.
     182                if ( in_array(
     183                    $fragment_context,
     184                    array(
     185                        'caption',
     186                        'col',
     187                        'colgroup',
     188                        'tbody',
     189                        'td',
     190                        'tfoot',
     191                        'th',
     192                        'thead',
     193                        'tr',
     194                    ),
     195                    true
     196                ) ) {
     197                    $fragment_context_html = "<table><{$fragment_context}>";
    187198                } else {
    188                     if ( in_array(
    189                         $fragment_context,
    190                         array(
    191                             'caption',
    192                             'col',
    193                             'colgroup',
    194                             'tbody',
    195                             'td',
    196                             'tfoot',
    197                             'th',
    198                             'thead',
    199                             'tr',
    200                         ),
    201                         true
    202                     ) ) {
    203                         $parent_processor = WP_HTML_Processor::create_full_parser( "<!DOCTYPE html><table><{$fragment_context}>" );
    204                         $parent_processor->next_tag();
    205                     } else {
    206                         $parent_processor = WP_HTML_Processor::create_full_parser( "<!DOCTYPE html><{$fragment_context}>" );
    207                     }
    208                     $parent_processor->next_tag( $fragment_context );
    209                 }
    210                 if ( null !== $parent_processor->get_unsupported_exception() ) {
    211                     throw $parent_processor->get_unsupported_exception();
    212                 }
    213                 if ( null !== $parent_processor->get_last_error() ) {
    214                     throw new Exception( $parent_processor->get_last_error() );
    215                 }
    216                 $processor = $parent_processor->create_fragment_at_current_node( $html );
    217             }
     199                    $fragment_context_html = "<{$fragment_context}>";
     200                }
     201            }
     202
     203            $processor = WP_HTML_Processor::create_fragment( $html, $fragment_context_html );
    218204
    219205            if ( null === $processor ) {
Note: See TracChangeset for help on using the changeset viewer.