WordPress.org

Make WordPress Core

Ticket #44427: 44427.7.diff

File 44427.7.diff, 9.7 KB (added by flixos90, 2 months ago)
  • src/wp-includes/default-filters.php

     
    260260add_filter( 'xmlrpc_pingback_error', 'xmlrpc_pingback_error' );
    261261add_filter( 'title_save_pre', 'trim' );
    262262
     263// Add lazy loading attributes to content.
     264foreach ( array( 'the_content', 'the_excerpt', 'comment_text', 'widget_text_content' ) as $filter ) {
     265        add_filter( $filter, 'wp_lazy_load_content_media' );
     266}
     267
    263268add_action( 'transition_comment_status', '_clear_modified_cache_on_transition_comment_status', 10, 2 );
    264269
    265270add_filter( 'http_request_host_is_external', 'allowed_http_request_hosts', 10, 2 );
  • src/wp-includes/formatting.php

     
    32963296                return $img;
    32973297        }
    32983298
     3299        $loading = '';
     3300        if ( in_array( 'img', wp_get_lazy_load_tags(), true ) ) {
     3301                $loading = 'loading="lazy"';
     3302        }
     3303
    32993304        /**
    33003305         * Filters the Smiley image URL before it's used in the image element.
    33013306         *
     
    33073312         */
    33083313        $src_url = apply_filters( 'smilies_src', includes_url( "images/smilies/$img" ), $img, site_url() );
    33093314
    3310         return sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', esc_url( $src_url ), esc_attr( $smiley ) );
     3315        return sprintf(
     3316                '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" %s />',
     3317                esc_url( $src_url ),
     3318                esc_attr( $smiley ),
     3319                $loading
     3320        );
    33113321}
    33123322
    33133323/**
  • src/wp-includes/media.php

     
    10131013                        'alt'   => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
    10141014                );
    10151015
     1016                if ( in_array( 'img', wp_get_lazy_load_tags(), true ) ) {
     1017                        $default_attr['loading'] = 'lazy';
     1018                }
     1019
    10161020                $attr = wp_parse_args( $attr, $default_attr );
    10171021
    10181022                // Generate 'srcset' and 'sizes' if not already present.
     
    15941598}
    15951599
    15961600/**
     1601 * Gets the tags to lazy-load.
     1602 *
     1603 * @since 5.4.0
     1604 *
     1605 * @return array List of tags to add loading="lazy" attributes to.
     1606 */
     1607function wp_get_lazy_load_tags() {
     1608        $supported_tags = array( 'img', 'iframe' );
     1609
     1610        /**
     1611         * Filters which media should be lazy-loaded with loading="lazy" attributes.
     1612         *
     1613         * @since 5.4.0
     1614         *
     1615         * @param array $tags List of tags to add loading="lazy" attributes to. Default is an array with 'img'.
     1616         */
     1617        $tags = apply_filters( 'wp_lazy_load_content_media', array( 'img' ) );
     1618
     1619        // Support a boolean, just in case.
     1620        if ( ! is_array( $tags ) ) {
     1621                return $tags ? $supported_tags : array();
     1622        }
     1623
     1624        // Only allow supported tags to be included.
     1625        return array_values( array_intersect( $tags, $supported_tags ) );
     1626}
     1627
     1628/**
     1629 * Filters 'img' and 'iframe' elements in post content to add 'loading' attributes.
     1630 *
     1631 * @since 5.4.0
     1632 *
     1633 * @param string $content The raw post content to be filtered.
     1634 * @return string Converted content with 'loading' attributes added to images.
     1635 */
     1636function wp_lazy_load_content_media( $content ) {
     1637        $tags = wp_get_lazy_load_tags();
     1638        if ( empty( $tags ) ) {
     1639                return $content;
     1640        }
     1641
     1642        return preg_replace_callback(
     1643                '/<(' . implode( '|', $tags ) . ')(\s)[^>]+>/',
     1644                function( array $matches ) {
     1645                        if ( ! preg_match( '/\sloading\s*=/', $matches[0] ) ) {
     1646                                $tag   = $matches[1];
     1647                                $space = $matches[2];
     1648                                return str_replace( '<' . $tag . $space, '<' . $tag . $space . 'loading="lazy" ', $matches[0] );
     1649                        }
     1650                        return $matches[0];
     1651                },
     1652                $content
     1653        );
     1654}
     1655
     1656/**
    15971657 * Adds a 'wp-post-image' class to post thumbnails. Internal use only.
    15981658 *
    15991659 * Uses the {@see 'begin_fetch_post_thumbnail_html'} and {@see 'end_fetch_post_thumbnail_html'}
  • src/wp-includes/pluggable.php

     
    25962596                        'extra_attr'    => '',
    25972597                );
    25982598
     2599                if ( in_array( 'img', wp_get_lazy_load_tags(), true ) ) {
     2600                        $defaults['loading'] = 'lazy';
     2601                }
     2602
    25992603                if ( empty( $args ) ) {
    26002604                        $args = array();
    26012605                }
     
    26652669                        }
    26662670                }
    26672671
     2672                $extra_attr = $args['extra_attr'];
     2673                if ( ! empty( $args['loading'] ) ) {
     2674                        if ( ! empty( $extra_attr ) ) {
     2675                                $extra_attr = ' ' . $extra_attr;
     2676                        }
     2677                        $extra_attr = 'loading="' . esc_attr( $args['loading'] ) . '"' . $extra_attr;
     2678                }
     2679
    26682680                $avatar = sprintf(
    26692681                        "<img alt='%s' src='%s' srcset='%s' class='%s' height='%d' width='%d' %s/>",
    26702682                        esc_attr( $args['alt'] ),
     
    26732685                        esc_attr( join( ' ', $class ) ),
    26742686                        (int) $args['height'],
    26752687                        (int) $args['width'],
    2676                         $args['extra_attr']
     2688                        $extra_attr
    26772689                );
    26782690
    26792691                /**
  • tests/phpunit/tests/media.php

     
    13011301         * Tests the default output of `wp_get_attachment_image()`.
    13021302         *
    13031303         * @ticket 34635
     1304         * @ticket 44427
    13041305         */
    13051306        function test_wp_get_attachment_image_defaults() {
    13061307                $image    = image_downsize( self::$large_id, 'thumbnail' );
    13071308                $expected = sprintf( '<img width="%1$d" height="%2$d" src="%3$s" class="attachment-thumbnail size-thumbnail" alt="" />', $image[1], $image[2], $image[0] );
    13081309
     1310                add_filter( 'wp_lazy_load_content_media', '__return_false' );
     1311                $this->assertEquals( $expected, wp_get_attachment_image( self::$large_id ) );
     1312
     1313                $expected = str_replace( ' alt=""', ' alt="" loading="lazy"', $expected );
     1314
     1315                remove_filter( 'wp_lazy_load_content_media', '__return_false' );
    13091316                $this->assertEquals( $expected, wp_get_attachment_image( self::$large_id ) );
    13101317        }
    13111318
     
    13191326                update_post_meta( self::$large_id, '_wp_attachment_image_alt', 'Some very clever alt text', true );
    13201327
    13211328                $image    = image_downsize( self::$large_id, 'thumbnail' );
    1322                 $expected = sprintf( '<img width="%1$d" height="%2$d" src="%3$s" class="attachment-thumbnail size-thumbnail" alt="Some very clever alt text" />', $image[1], $image[2], $image[0] );
     1329                $expected = sprintf( '<img width="%1$d" height="%2$d" src="%3$s" class="attachment-thumbnail size-thumbnail" alt="Some very clever alt text" loading="lazy" />', $image[1], $image[2], $image[0] );
    13231330
    13241331                $this->assertEquals( $expected, wp_get_attachment_image( self::$large_id ) );
    13251332
     
    22322239                $month  = gmdate( 'm' );
    22332240
    22342241                $expected = '<img width="999" height="999" src="http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year . '/' . $month . '/test-image-testsize-999x999.png"' .
    2235                         ' class="attachment-testsize size-testsize" alt=""' .
     2242                        ' class="attachment-testsize size-testsize" alt="" loading="lazy"' .
    22362243                        ' srcset="http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year . '/' . $month . '/test-image-testsize-999x999.png 999w,' .
    22372244                                ' http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year . '/' . $month . '/test-image-large-150x150.png 150w"' .
    22382245                                ' sizes="(max-width: 999px) 100vw, 999px" />';
     
    24952502
    24962503                $this->assertSame( $expected, $url );
    24972504        }
     2505
     2506        /**
     2507         * @ticket 44427
     2508         */
     2509        function test_wp_lazy_load_content_media() {
     2510                $img       = get_image_tag( self::$large_id, '', '', '', 'medium' );
     2511                $img_xhtml = str_replace( ' />', '/>', $img );
     2512                $img_html5 = str_replace( ' />', '>', $img );
     2513                $iframe    = '<iframe src="https://www.example.com"></iframe>';
     2514
     2515                $lazy_img       = str_replace( '<img ', '<img loading="lazy" ', $img );
     2516                $lazy_img_xhtml = str_replace( '<img ', '<img loading="lazy" ', $img_xhtml );
     2517                $lazy_img_html5 = str_replace( '<img ', '<img loading="lazy" ', $img_html5 );
     2518
     2519                // The following should not be modified because there already is a 'loading' attribute.
     2520                $img_eager = str_replace( ' />', ' loading="eager" />', $img );
     2521
     2522                $content = '
     2523                        <p>Image, standard.</p>
     2524                        %1$s
     2525
     2526                        <p>Image, XHTML 1.0 style (no space before the closing slash).</p>
     2527                        %2$s
     2528
     2529                        <p>Image, HTML 5.0 style.</p>
     2530                        %3$s
     2531
     2532                        <p>Image, with pre-existing "loading" attribute.</p>
     2533                        %5$s
     2534
     2535                        <p>Iframe, standard. Should not be modified by default.</p>
     2536                        %4$s';
     2537
     2538                $content_unfiltered = sprintf( $content, $img, $img_xhtml, $img_html5, $iframe, $img_eager );
     2539                $content_filtered   = sprintf( $content, $lazy_img, $lazy_img_xhtml, $lazy_img_html5, $iframe, $img_eager );
     2540
     2541                $this->assertSame( $content_filtered, wp_lazy_load_content_media( $content_unfiltered ) );
     2542        }
     2543
     2544        /**
     2545         * @ticket 44427
     2546         */
     2547        function test_wp_lazy_load_content_media_opted_in() {
     2548                $img    = get_image_tag( self::$large_id, '', '', '', 'medium' );
     2549                $iframe = '<iframe src="https://www.example.com"></iframe>';
     2550
     2551                $lazy_img    = str_replace( '<img ', '<img loading="lazy" ', $img );
     2552                $lazy_iframe = str_replace( '<iframe ', '<iframe loading="lazy" ', $iframe );
     2553
     2554                $content = '
     2555                        <p>Image, standard.</p>
     2556                        %1$s
     2557
     2558                        <p>Iframe, standard.</p>
     2559                        %2$s';
     2560
     2561                $content_unfiltered = sprintf( $content, $img, $iframe );
     2562                $content_filtered   = sprintf( $content, $lazy_img, $lazy_iframe );
     2563
     2564                add_filter( 'wp_lazy_load_content_media', '__return_true' );
     2565                $this->assertSame( $content_filtered, wp_lazy_load_content_media( $content_unfiltered ) );
     2566        }
     2567
     2568        /**
     2569         * @ticket 44427
     2570         */
     2571        function test_wp_lazy_load_content_media_opted_out() {
     2572                $img = get_image_tag( self::$large_id, '', '', '', 'medium' );
     2573
     2574                $content = '
     2575                        <p>Image, standard.</p>
     2576                        %1$s';
     2577                $content = sprintf( $content, $img );
     2578
     2579                add_filter( 'wp_lazy_load_content_media', '__return_false' );
     2580                $this->assertSame( $content, wp_lazy_load_content_media( $content ) );
     2581        }
    24982582}
    24992583
    25002584/**