Make WordPress Core

Changeset 38826


Ignore:
Timestamp:
10/19/2016 09:28:22 AM (8 years ago)
Author:
swissspidy
Message:

Resource Hints: Allow passing custom attributes to resource hints.

[37920] introduced resource hints that allow browsers to prefetch specific pages or render them in the background. With this change, the as, crossorigin, pr, and type attributes can be passed in addition to the URLs/hosts.

Props peterwilsoncc, swissspidy.
Fixes #38121.

Location:
trunk
Files:
2 edited

Legend:

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

    r38786 r38826  
    28312831
    28322832    foreach ( $hints as $relation_type => $urls ) {
     2833        $unique_urls = array();
     2834
    28332835        /**
    28342836         * Filters domains and URLs for resource hints of relation type.
     
    28422844
    28432845        foreach ( $urls as $key => $url ) {
     2846            $atts = array();
     2847
     2848            if ( is_array( $url ) ) {
     2849                if ( isset( $url['href'] ) ) {
     2850                    $atts = $url;
     2851                    $url  = $url['href'];
     2852                } else {
     2853                    continue;
     2854                }
     2855            }
     2856
    28442857            $url = esc_url( $url, array( 'http', 'https' ) );
     2858
    28452859            if ( ! $url ) {
    2846                 unset( $urls[ $key ] );
    28472860                continue;
    28482861            }
    28492862
     2863            if ( isset( $unique_urls[ $url ] ) ) {
     2864                continue;
     2865            }
     2866
    28502867            if ( in_array( $relation_type, array( 'preconnect', 'dns-prefetch' ) ) ) {
    28512868                $parsed = wp_parse_url( $url );
     2869
    28522870                if ( empty( $parsed['host'] ) ) {
    2853                     unset( $urls[ $key ] );
    28542871                    continue;
    28552872                }
     
    28632880            }
    28642881
    2865             $urls[ $key ] = $url;
     2882            $atts['rel'] = $relation_type;
     2883            $atts['href'] = $url;
     2884
     2885            $unique_urls[ $url ] = $atts;
    28662886        }
    28672887
    2868         $urls = array_unique( $urls );
    2869 
    2870         foreach ( $urls as $url ) {
    2871             printf( "<link rel='%s' href='%s' />\n", $relation_type, $url );
     2888        foreach ( $unique_urls as $atts ) {
     2889            $html = '';
     2890
     2891            foreach ( $atts as $attr => $value ) {
     2892                if ( ! is_scalar( $value ) ||
     2893                     ( ! in_array( $attr, array( 'as', 'crossorigin', 'href', 'pr', 'rel', 'type' ), true ) && ! is_numeric( $attr ))
     2894                ) {
     2895                    continue;
     2896                }
     2897
     2898                $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
     2899
     2900                if ( ! is_string( $attr ) ) {
     2901                    $html .= " $value";
     2902                } else {
     2903                    $html .= " $attr='$value'";
     2904                }
     2905            }
     2906
     2907            $html = trim( $html );
     2908
     2909            echo "<link $html />\n";
    28722910        }
    28732911    }
  • trunk/tests/phpunit/tests/general/resourceHints.php

    r38447 r38826  
    22
    33/**
    4  * @group  template
     4 * @group template
    55 * @ticket 34292
    66 */
     
    243243        return $hints;
    244244    }
     245
     246    /**
     247     * @group 38121
     248     */
     249    function test_custom_attributes() {
     250        $expected = "<link rel='dns-prefetch' href='//s.w.org' />\n" .
     251                    "<link rel='preconnect' href='https://make.wordpress.org' />\n" .
     252                    "<link crossorigin as='image' pr='0.5' href='https://example.com/foo.jpeg' rel='prefetch' />\n" .
     253                    "<link crossorigin='use-credentials' as='style' href='https://example.com/foo.css' rel='prefetch' />\n" .
     254                    "<link href='http://wordpress.org' rel='prerender' />\n";
     255
     256        add_filter( 'wp_resource_hints', array( $this, '_add_url_with_attributes' ), 10, 2 );
     257
     258        $actual = get_echo( 'wp_resource_hints' );
     259
     260        remove_filter( 'wp_resource_hints', array( $this, '_add_url_with_attributes' ) );
     261
     262        $this->assertEquals( $expected, $actual );
     263    }
     264
     265    function _add_url_with_attributes( $hints, $method ) {
     266        // Ignore hints with missing href attributes.
     267        $hints[] = array(
     268            'rel'  => 'foo',
     269        );
     270
     271        if ( 'preconnect' === $method ) {
     272            // Should ignore rel attributes.
     273            $hints[] = array(
     274                'rel'  => 'foo',
     275                'href' => 'https://make.wordpress.org/great-again',
     276            );
     277        } elseif ( 'prefetch' === $method ) {
     278            $hints[] = array(
     279                'crossorigin',
     280                'as'   => 'image',
     281                'pr'   => 0.5,
     282                'href' => 'https://example.com/foo.jpeg',
     283            );
     284            $hints[] = array(
     285                'crossorigin' => 'use-credentials',
     286                'as'          => 'style',
     287                'href'        => 'https://example.com/foo.css',
     288            );
     289        } elseif ( 'prerender' === $method ) {
     290            // Ignore invalid attributes.
     291            $hints[] = array(
     292                'foo'  => 'bar',
     293                'bar'  => 'baz',
     294                'href' => 'http://wordpress.org',
     295            );
     296        }
     297
     298        return $hints;
     299    }
    245300}
Note: See TracChangeset for help on using the changeset viewer.