Make WordPress Core

Ticket #59599: 58599.3.diff

File 58599.3.diff, 10.3 KB (added by adamsilverstein, 9 months ago)
  • src/wp-includes/class-wp-scripts.php

    diff --git src/wp-includes/class-wp-scripts.php src/wp-includes/class-wp-scripts.php
    index a6a283f953..116e98f673 100644
    class WP_Scripts extends WP_Dependencies { 
    231231                return true;
    232232        }
    233233
     234        /**
     235         * Checks whether all dependents of a given handle are in the footer.
     236         *
     237         * If there are no dependents, this is considered the same as if all dependents were in the footer.
     238         *
     239         * @since 6.4.0
     240         *
     241         * @param string $handle Script handle.
     242         * @return bool Whether all dependents are in the footer.
     243         */
     244        private function are_all_dependents_in_footer( $handle ) {
     245                foreach ( $this->get_dependents( $handle ) as $dep ) {
     246                        if ( isset( $this->groups[ $dep ] ) && 0 === $this->groups[ $dep ] ) {
     247                                return false;
     248                        }
     249                }
     250                return true;
     251        }
     252
    234253        /**
    235254         * Processes a script dependency.
    236255         *
    class WP_Scripts extends WP_Dependencies { 
    281300                        $intended_strategy = '';
    282301                }
    283302
     303                /*
     304                 * Move this script to the footer if:
     305                 * 1. The script is in the header group.
     306                 * 2. The current output is the header.
     307                 * 3. The intended strategy is delayed.
     308                 * 4. The actual strategy is not delayed.
     309                 * 5. All dependent scripts are in the footer.
     310                 */
     311                if (
     312                        0 === $group &&
     313                        0 === $this->groups[ $handle ] &&
     314                        $intended_strategy &&
     315                        ! $this->is_delayed_strategy( $strategy ) &&
     316                        $this->are_all_dependents_in_footer( $handle )
     317                ) {
     318                        $this->in_footer[] = $handle;
     319                        return false;
     320                }
     321
    284322                if ( $conditional ) {
    285323                        $cond_before = "<!--[if {$conditional}]>\n";
    286324                        $cond_after  = "<![endif]-->\n";
  • tests/phpunit/tests/dependencies/scripts.php

    diff --git tests/phpunit/tests/dependencies/scripts.php tests/phpunit/tests/dependencies/scripts.php
    index 7f2b956127..3589a77578 100644
    HTML 
    30653065        protected function add_html5_script_theme_support() {
    30663066                add_theme_support( 'html5', array( 'script' ) );
    30673067        }
     3068
     3069        /**
     3070         * Test that a script is moved to the footer if it is made non-deferrable, was in the header and
     3071         * all scripts that depend on it are in the footer.
     3072         *
     3073         * @ticket 58599
     3074         *
     3075         * @dataProvider data_provider_script_move_to_footer
     3076         *
     3077         * @param callable $set_up             Test setup.
     3078         * @param string   $expected_header    Expected output for header.
     3079         * @param string   $expected_footer    Expected output for footer.
     3080         * @param string[] $expected_in_footer Handles expected to be in the footer.
     3081         */
     3082        public function test_wp_scripts_move_to_footer( $set_up, $expected_header, $expected_footer, $expected_in_footer ) {
     3083                $set_up();
     3084
     3085                // Get the header output.
     3086                ob_start();
     3087                wp_scripts()->do_head_items();
     3088                $header = ob_get_clean();
     3089
     3090                // Print a script in the body just to make sure it doesn't cause problems.
     3091                ob_start();
     3092                wp_print_scripts( array( 'jquery' ) );
     3093                ob_end_clean();
     3094
     3095                // Get the footer output.
     3096                ob_start();
     3097                wp_scripts()->do_footer_items();
     3098                $footer = ob_get_clean();
     3099
     3100                $this->assertEqualMarkup( $expected_header, $header, 'Expected header script markup to match.' );
     3101                $this->assertEqualMarkup( $expected_footer, $footer, 'Expected footer script markup to match.' );
     3102                $this->assertEqualSets( $expected_in_footer, wp_scripts()->in_footer, 'Expected to have the same handles for in_footer.' );
     3103        }
     3104
     3105        /**
     3106         * Data provider for test_wp_scripts_move_to_footer.
     3107         *
     3108         * @return array[]
     3109         */
     3110        public function data_provider_script_move_to_footer() {
     3111                return array(
     3112                        'footer-blocking-dependent-of-delayed-head-script' => array(
     3113                                'set_up'             => static function () {
     3114                                        wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
     3115                                        wp_enqueue_script( 'script-b', 'https://example.com/script-b.js', array( 'script-a' ), null, array( 'in_footer' => true ) );
     3116                                },
     3117                                'expected_header'    => '',
     3118                                'expected_footer'    => '
     3119                                        <script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" data-wp-strategy="defer"></script>
     3120                                        <script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js"></script>
     3121                                ',
     3122                                'expected_in_footer' => array(
     3123                                        'script-a',
     3124                                        'script-b',
     3125                                ),
     3126                        ),
     3127
     3128                        'head-blocking-dependent-of-delayed-head-script' => array(
     3129                                'set_up'             => static function () {
     3130                                        wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
     3131                                        wp_enqueue_script( 'script-b', 'https://example.com/script-b.js', array( 'script-a' ), null, array( 'in_footer' => false ) );
     3132                                },
     3133                                'expected_header'    => '
     3134                                        <script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" data-wp-strategy="defer"></script>
     3135                                        <script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js"></script>
     3136                                ',
     3137                                'expected_footer'    => '',
     3138                                'expected_in_footer' => array(),
     3139                        ),
     3140
     3141                        'delayed-footer-dependent-of-delayed-head-script' => array(
     3142                                'set_up'             => static function () {
     3143                                        wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
     3144                                        wp_enqueue_script(
     3145                                                'script-b',
     3146                                                'https://example.com/script-b.js',
     3147                                                array( 'script-a' ),
     3148                                                null,
     3149                                                array(
     3150                                                        'strategy'  => 'defer',
     3151                                                        'in_footer' => true,
     3152                                                )
     3153                                        );
     3154                                },
     3155                                'expected_header'    => '
     3156                                        <script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" defer="defer" data-wp-strategy="defer"></script>
     3157                                ',
     3158                                'expected_footer'    => '
     3159                                        <script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js" defer="defer" data-wp-strategy="defer"></script>
     3160                                ',
     3161                                'expected_in_footer' => array(
     3162                                        'script-b',
     3163                                ),
     3164                        ),
     3165
     3166                        'delayed-dependent-in-header-and-delayed-dependents-in-footer' => array(
     3167                                'set_up'             => static function () {
     3168                                        wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
     3169                                        wp_enqueue_script(
     3170                                                'script-b',
     3171                                                'https://example.com/script-b.js',
     3172                                                array( 'script-a' ),
     3173                                                null,
     3174                                                array(
     3175                                                        'strategy'  => 'defer',
     3176                                                        'in_footer' => false,
     3177                                                )
     3178                                        );
     3179                                        wp_enqueue_script(
     3180                                                'script-c',
     3181                                                'https://example.com/script-c.js',
     3182                                                array( 'script-a' ),
     3183                                                null,
     3184                                                array(
     3185                                                        'strategy'  => 'defer',
     3186                                                        'in_footer' => true,
     3187                                                )
     3188                                        );
     3189                                        wp_enqueue_script(
     3190                                                'script-d',
     3191                                                'https://example.com/script-d.js',
     3192                                                array( 'script-a' ),
     3193                                                null,
     3194                                                array(
     3195                                                        'strategy'  => 'defer',
     3196                                                        'in_footer' => true,
     3197                                                )
     3198                                        );
     3199                                },
     3200                                'expected_header'    => '
     3201                                        <script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" defer="defer" data-wp-strategy="defer"></script>
     3202                                        <script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js" defer="defer" data-wp-strategy="defer"></script>
     3203                                ',
     3204                                'expected_footer'    => '
     3205                                        <script type="text/javascript" src="https://example.com/script-c.js" id="script-c-js" defer="defer" data-wp-strategy="defer"></script>
     3206                                        <script type="text/javascript" src="https://example.com/script-d.js" id="script-d-js" defer="defer" data-wp-strategy="defer"></script>
     3207                                ',
     3208                                'expected_in_footer' => array(
     3209                                        'script-c',
     3210                                        'script-d',
     3211                                ),
     3212                        ),
     3213
     3214                        'all-dependents-in-footer-with-one-blocking' => array(
     3215                                'set_up'          => static function () {
     3216                                        wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
     3217                                        wp_enqueue_script(
     3218                                                'script-b',
     3219                                                'https://example.com/script-b.js',
     3220                                                array( 'script-a' ),
     3221                                                null,
     3222                                                array(
     3223                                                        'strategy'  => 'defer',
     3224                                                        'in_footer' => true,
     3225                                                )
     3226                                        );
     3227                                        wp_enqueue_script( 'script-c', 'https://example.com/script-c.js', array( 'script-a' ), null, true );
     3228                                        wp_enqueue_script(
     3229                                                'script-d',
     3230                                                'https://example.com/script-d.js',
     3231                                                array( 'script-a' ),
     3232                                                null,
     3233                                                array(
     3234                                                        'strategy'  => 'defer',
     3235                                                        'in_footer' => true,
     3236                                                )
     3237                                        );
     3238                                },
     3239                                'expected_header' => '',
     3240                                'expected_footer' => '
     3241                                        <script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" data-wp-strategy="defer"></script>
     3242                                        <script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js" defer="defer" data-wp-strategy="defer"></script>
     3243                                        <script type="text/javascript" src="https://example.com/script-c.js" id="script-c-js"></script>
     3244                                        <script type="text/javascript" src="https://example.com/script-d.js" id="script-d-js" defer="defer" data-wp-strategy="defer"></script>
     3245                                ',
     3246                                array(
     3247                                        'script-a',
     3248                                        'script-b',
     3249                                        'script-c',
     3250                                        'script-d',
     3251                                ),
     3252                        ),
     3253
     3254                        'blocking-dependents-in-head-and-footer'     => array(
     3255                                'set_up'          => static function () {
     3256                                        wp_enqueue_script( 'script-a', 'https://example.com/script-a.js', array(), null, array( 'strategy' => 'defer' ) );
     3257                                        wp_enqueue_script(
     3258                                                'script-b',
     3259                                                'https://example.com/script-b.js',
     3260                                                array( 'script-a' ),
     3261                                                null,
     3262                                                array(
     3263                                                        'strategy'  => 'defer',
     3264                                                        'in_footer' => false,
     3265                                                )
     3266                                        );
     3267                                        wp_enqueue_script( 'script-c', 'https://example.com/script-c.js', array( 'script-a' ), null, true );
     3268                                        wp_enqueue_script(
     3269                                                'script-d',
     3270                                                'https://example.com/script-d.js',
     3271                                                array( 'script-a' ),
     3272                                                null,
     3273                                                array(
     3274                                                        'strategy'  => 'defer',
     3275                                                        'in_footer' => true,
     3276                                                )
     3277                                        );
     3278                                },
     3279                                'expected_header' => '
     3280                                        <script type="text/javascript" src="https://example.com/script-a.js" id="script-a-js" data-wp-strategy="defer"></script>
     3281                                        <script type="text/javascript" src="https://example.com/script-b.js" id="script-b-js" defer="defer" data-wp-strategy="defer"></script>
     3282                                ',
     3283                                'expected_footer' => '
     3284                                        <script type="text/javascript" src="https://example.com/script-c.js" id="script-c-js"></script>
     3285                                        <script type="text/javascript" src="https://example.com/script-d.js" id="script-d-js" defer="defer" data-wp-strategy="defer"></script>
     3286                                ',
     3287                                array(
     3288                                        'script-c',
     3289                                        'script-d',
     3290                                ),
     3291                        ),
     3292
     3293                );
     3294        }
    30683295}