Changeset 60704
- Timestamp:
- 09/03/2025 10:15:31 PM (4 months ago)
- Location:
- trunk
- Files:
-
- 8 edited
-
src/wp-includes/blocks.php (modified) (1 diff)
-
src/wp-includes/class-wp-script-modules.php (modified) (8 diffs)
-
src/wp-includes/class-wp-scripts.php (modified) (4 diffs)
-
src/wp-includes/functions.wp-scripts.php (modified) (6 diffs)
-
src/wp-includes/script-loader.php (modified) (1 diff)
-
src/wp-includes/script-modules.php (modified) (5 diffs)
-
tests/phpunit/tests/dependencies/scripts.php (modified) (1 diff)
-
tests/phpunit/tests/script-modules/wpScriptModules.php (modified) (35 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/blocks.php
r60511 r60704 176 176 $module_version = isset( $module_asset['version'] ) ? $module_asset['version'] : $block_version; 177 177 178 // Blocks using the Interactivity API are server-side rendered, so they are by design not in the critical rendering path and should be deprioritized. 179 $args = array(); 180 if ( 181 ( isset( $metadata['supports']['interactivity'] ) && true === $metadata['supports']['interactivity'] ) || 182 ( isset( $metadata['supports']['interactivity']['interactive'] ) && true === $metadata['supports']['interactivity']['interactive'] ) 183 ) { 184 $args['fetchpriority'] = 'low'; 185 } 186 178 187 wp_register_script_module( 179 188 $module_id, 180 189 $module_uri, 181 190 $module_dependencies, 182 $module_version 191 $module_version, 192 $args 183 193 ); 184 194 -
trunk/src/wp-includes/class-wp-script-modules.php
r60681 r60704 47 47 * 48 48 * @since 6.5.0 49 * @since 6.9.0 Added the $args parameter. 49 50 * 50 51 * @param string $id The identifier of the script module. Should be unique. It will be used in the … … 72 73 * is set to false, the version number is the currently installed WordPress version. 73 74 * If $version is set to null, no version is added. 74 */ 75 public function register( string $id, string $src, array $deps = array(), $version = false ) { 75 * @param array $args { 76 * Optional. An array of additional args. Default empty array. 77 * 78 * @type 'auto'|'low'|'high' $fetchpriority Fetch priority. Default 'auto'. Optional. 79 * } 80 */ 81 public function register( string $id, string $src, array $deps = array(), $version = false, array $args = array() ) { 76 82 if ( ! isset( $this->registered[ $id ] ) ) { 77 83 $dependencies = array(); 78 84 foreach ( $deps as $dependency ) { 79 85 if ( is_array( $dependency ) ) { 80 if ( ! isset( $dependency['id'] ) ) {86 if ( ! isset( $dependency['id'] ) || ! is_string( $dependency['id'] ) ) { 81 87 _doing_it_wrong( __METHOD__, __( 'Missing required id key in entry among dependencies array.' ), '6.5.0' ); 82 88 continue; … … 96 102 } 97 103 104 $fetchpriority = 'auto'; 105 if ( isset( $args['fetchpriority'] ) ) { 106 if ( $this->is_valid_fetchpriority( $args['fetchpriority'] ) ) { 107 $fetchpriority = $args['fetchpriority']; 108 } else { 109 _doing_it_wrong( 110 __METHOD__, 111 sprintf( 112 /* translators: 1: $fetchpriority, 2: $id */ 113 __( 'Invalid fetchpriority `%1$s` defined for `%2$s` during script registration.' ), 114 is_string( $args['fetchpriority'] ) ? $args['fetchpriority'] : gettype( $args['fetchpriority'] ), 115 $id 116 ), 117 '6.9.0' 118 ); 119 } 120 } 121 98 122 $this->registered[ $id ] = array( 99 'src' => $src, 100 'version' => $version, 101 'enqueue' => isset( $this->enqueued_before_registered[ $id ] ), 102 'dependencies' => $dependencies, 123 'src' => $src, 124 'version' => $version, 125 'enqueue' => isset( $this->enqueued_before_registered[ $id ] ), 126 'dependencies' => $dependencies, 127 'fetchpriority' => $fetchpriority, 103 128 ); 104 129 } 130 } 131 132 /** 133 * Checks if the provided fetchpriority is valid. 134 * 135 * @since 6.9.0 136 * 137 * @param string|mixed $priority Fetch priority. 138 * @return bool Whether valid fetchpriority. 139 */ 140 private function is_valid_fetchpriority( $priority ): bool { 141 return in_array( $priority, array( 'auto', 'low', 'high' ), true ); 142 } 143 144 /** 145 * Sets the fetch priority for a script module. 146 * 147 * @since 6.9.0 148 * 149 * @param string $id Script module identifier. 150 * @param 'auto'|'low'|'high' $priority Fetch priority for the script module. 151 * @return bool Whether setting the fetchpriority was successful. 152 */ 153 public function set_fetchpriority( string $id, string $priority ): bool { 154 if ( ! isset( $this->registered[ $id ] ) ) { 155 return false; 156 } 157 158 if ( '' === $priority ) { 159 $priority = 'auto'; 160 } 161 162 if ( ! $this->is_valid_fetchpriority( $priority ) ) { 163 _doing_it_wrong( 164 __METHOD__, 165 /* translators: %s: Invalid fetchpriority. */ 166 sprintf( __( 'Invalid fetchpriority: %s' ), $priority ), 167 '6.9.0' 168 ); 169 return false; 170 } 171 172 $this->registered[ $id ]['fetchpriority'] = $priority; 173 return true; 105 174 } 106 175 … … 112 181 * 113 182 * @since 6.5.0 183 * @since 6.9.0 Added the $args parameter. 114 184 * 115 185 * @param string $id The identifier of the script module. Should be unique. It will be used in the … … 137 207 * is set to false, the version number is the currently installed WordPress version. 138 208 * If $version is set to null, no version is added. 139 */ 140 public function enqueue( string $id, string $src = '', array $deps = array(), $version = false ) { 209 * @param array $args { 210 * Optional. An array of additional args. Default empty array. 211 * 212 * @type 'auto'|'low'|'high' $fetchpriority Fetch priority. Default 'auto'. Optional. 213 * } 214 */ 215 public function enqueue( string $id, string $src = '', array $deps = array(), $version = false, array $args = array() ) { 141 216 if ( isset( $this->registered[ $id ] ) ) { 142 217 $this->registered[ $id ]['enqueue'] = true; 143 218 } elseif ( $src ) { 144 $this->register( $id, $src, $deps, $version );219 $this->register( $id, $src, $deps, $version, $args ); 145 220 $this->registered[ $id ]['enqueue'] = true; 146 221 } else { … … 209 284 public function print_enqueued_script_modules() { 210 285 foreach ( $this->get_marked_for_enqueue() as $id => $script_module ) { 211 wp_print_script_tag( 212 array( 213 'type' => 'module', 214 'src' => $this->get_src( $id ), 215 'id' => $id . '-js-module', 216 ) 286 $args = array( 287 'type' => 'module', 288 'src' => $this->get_src( $id ), 289 'id' => $id . '-js-module', 217 290 ); 291 if ( 'auto' !== $script_module['fetchpriority'] ) { 292 $args['fetchpriority'] = $script_module['fetchpriority']; 293 } 294 wp_print_script_tag( $args ); 218 295 } 219 296 } … … 232 309 if ( true !== $script_module['enqueue'] ) { 233 310 echo sprintf( 234 '<link rel="modulepreload" href="%s" id="%s" >',311 '<link rel="modulepreload" href="%s" id="%s"%s>', 235 312 esc_url( $this->get_src( $id ) ), 236 esc_attr( $id . '-js-modulepreload' ) 313 esc_attr( $id . '-js-modulepreload' ), 314 'auto' !== $script_module['fetchpriority'] ? sprintf( ' fetchpriority="%s"', esc_attr( $script_module['fetchpriority'] ) ) : '' 237 315 ); 238 316 } … … 279 357 * @since 6.5.0 280 358 * 281 * @return array []Script modules marked for enqueue, keyed by script module identifier.359 * @return array<string, array> Script modules marked for enqueue, keyed by script module identifier. 282 360 */ 283 361 private function get_marked_for_enqueue(): array { -
trunk/src/wp-includes/class-wp-scripts.php
r60690 r60704 425 425 if ( $intended_strategy ) { 426 426 $attr['data-wp-strategy'] = $intended_strategy; 427 } 428 if ( isset( $obj->extra['fetchpriority'] ) && 'auto' !== $obj->extra['fetchpriority'] && $this->is_valid_fetchpriority( $obj->extra['fetchpriority'] ) ) { 429 $attr['fetchpriority'] = $obj->extra['fetchpriority']; 427 430 } 428 431 $tag = $translations . $ie_conditional_prefix . $before_script; … … 832 835 return false; 833 836 } 837 } elseif ( 'fetchpriority' === $key ) { 838 if ( empty( $value ) ) { 839 $value = 'auto'; 840 } 841 if ( ! $this->is_valid_fetchpriority( $value ) ) { 842 _doing_it_wrong( 843 __METHOD__, 844 sprintf( 845 /* translators: 1: $fetchpriority, 2: $handle */ 846 __( 'Invalid fetchpriority `%1$s` defined for `%2$s` during script registration.' ), 847 is_string( $value ) ? $value : gettype( $value ), 848 $handle 849 ), 850 '6.9.0' 851 ); 852 return false; 853 } elseif ( ! $this->registered[ $handle ]->src ) { 854 _doing_it_wrong( 855 __METHOD__, 856 sprintf( 857 /* translators: 1: $fetchpriority, 2: $handle */ 858 __( 'Cannot supply a fetchpriority `%1$s` for script `%2$s` because it is an alias (it lacks a `src` value).' ), 859 is_string( $value ) ? $value : gettype( $value ), 860 $handle 861 ), 862 '6.9.0' 863 ); 864 return false; 865 } 834 866 } 835 867 return parent::add_data( $handle, $key, $value ); … … 870 902 * @since 6.3.0 871 903 * 872 * @param string $strategy The strategy to check.904 * @param string|mixed $strategy The strategy to check. 873 905 * @return bool True if $strategy is one of the delayed strategies, otherwise false. 874 906 */ 875 private function is_delayed_strategy( $strategy ) {907 private function is_delayed_strategy( $strategy ): bool { 876 908 return in_array( 877 909 $strategy, … … 879 911 true 880 912 ); 913 } 914 915 /** 916 * Checks if the provided fetchpriority is valid. 917 * 918 * @since 6.9.0 919 * 920 * @param string|mixed $priority Fetch priority. 921 * @return bool Whether valid fetchpriority. 922 */ 923 private function is_valid_fetchpriority( $priority ): bool { 924 return in_array( $priority, array( 'auto', 'low', 'high' ), true ); 881 925 } 882 926 -
trunk/src/wp-includes/functions.wp-scripts.php
r58200 r60704 159 159 * @since 4.3.0 A return value was added. 160 160 * @since 6.3.0 The $in_footer parameter of type boolean was overloaded to be an $args parameter of type array. 161 * @since 6.9.0 The $fetchpriority parameter of type string was added to the $args parameter of type array. 161 162 * 162 163 * @param string $handle Name of the script. Should be unique. … … 172 173 * Otherwise, it may be a boolean in which case it determines whether the script is printed in the footer. Default false. 173 174 * 174 * @type string $strategy Optional. If provided, may be either 'defer' or 'async'. 175 * @type bool $in_footer Optional. Whether to print the script in the footer. Default 'false'. 175 * @type string $strategy Optional. If provided, may be either 'defer' or 'async'. 176 * @type bool $in_footer Optional. Whether to print the script in the footer. Default 'false'. 177 * @type string $fetchpriority Optional. The fetch priority for the script. Default 'auto'. 176 178 * } 177 179 * @return bool Whether the script has been registered. True on success, false on failure. … … 193 195 if ( ! empty( $args['strategy'] ) ) { 194 196 $wp_scripts->add_data( $handle, 'strategy', $args['strategy'] ); 197 } 198 if ( ! empty( $args['fetchpriority'] ) ) { 199 $wp_scripts->add_data( $handle, 'fetchpriority', $args['fetchpriority'] ); 195 200 } 196 201 return $registered; … … 340 345 * @since 2.1.0 341 346 * @since 6.3.0 The $in_footer parameter of type boolean was overloaded to be an $args parameter of type array. 347 * @since 6.9.0 The $fetchpriority parameter of type string was added to the $args parameter of type array. 342 348 * 343 349 * @param string $handle Name of the script. Should be unique. … … 353 359 * Otherwise, it may be a boolean in which case it determines whether the script is printed in the footer. Default false. 354 360 * 355 * @type string $strategy Optional. If provided, may be either 'defer' or 'async'. 356 * @type bool $in_footer Optional. Whether to print the script in the footer. Default 'false'. 361 * @type string $strategy Optional. If provided, may be either 'defer' or 'async'. 362 * @type bool $in_footer Optional. Whether to print the script in the footer. Default 'false'. 363 * @type string $fetchpriority Optional. The fetch priority for the script. Default 'auto'. 357 364 * } 358 365 */ … … 379 386 $wp_scripts->add_data( $_handle[0], 'strategy', $args['strategy'] ); 380 387 } 388 if ( ! empty( $args['fetchpriority'] ) ) { 389 $wp_scripts->add_data( $_handle[0], 'fetchpriority', $args['fetchpriority'] ); 390 } 381 391 } 382 392 -
trunk/src/wp-includes/script-loader.php
r60681 r60704 1048 1048 1049 1049 $scripts->add( 'comment-reply', "/wp-includes/js/comment-reply$suffix.js", array(), false, 1 ); 1050 did_action( 'init' ) && $scripts->add_data( 'comment-reply', 'strategy', 'async' ); 1050 if ( did_action( 'init' ) ) { 1051 $scripts->add_data( 'comment-reply', 'strategy', 'async' ); 1052 $scripts->add_data( 'comment-reply', 'fetchpriority', 'low' ); // In Chrome this is automatically low due to the async strategy, but in Firefox and Safari the priority is normal/medium. 1053 } 1051 1054 1052 1055 $scripts->add( 'json2', "/wp-includes/js/json2$suffix.js", array(), '2015-05-03' ); -
trunk/src/wp-includes/script-modules.php
r59223 r60704 36 36 * 37 37 * @since 6.5.0 38 * @since 6.9.0 Added the $args parameter. 38 39 * 39 40 * @param string $id The identifier of the script module. Should be unique. It will be used in the … … 61 62 * is set to false, the version number is the currently installed WordPress version. 62 63 * If $version is set to null, no version is added. 64 * @param array $args { 65 * Optional. An array of additional args. Default empty array. 66 * 67 * @type 'auto'|'low'|'high' $fetchpriority Fetch priority. Default 'auto'. Optional. 68 * } 63 69 */ 64 function wp_register_script_module( string $id, string $src, array $deps = array(), $version = false ) {65 wp_script_modules()->register( $id, $src, $deps, $version );70 function wp_register_script_module( string $id, string $src, array $deps = array(), $version = false, array $args = array() ) { 71 wp_script_modules()->register( $id, $src, $deps, $version, $args ); 66 72 } 67 73 … … 73 79 * 74 80 * @since 6.5.0 81 * @since 6.9.0 Added the $args parameter. 75 82 * 76 83 * @param string $id The identifier of the script module. Should be unique. It will be used in the … … 98 105 * is set to false, the version number is the currently installed WordPress version. 99 106 * If $version is set to null, no version is added. 107 * @param array $args { 108 * Optional. An array of additional args. Default empty array. 109 * 110 * @type 'auto'|'low'|'high' $fetchpriority Fetch priority. Default 'auto'. Optional. 111 * } 100 112 */ 101 function wp_enqueue_script_module( string $id, string $src = '', array $deps = array(), $version = false ) {102 wp_script_modules()->enqueue( $id, $src, $deps, $version );113 function wp_enqueue_script_module( string $id, string $src = '', array $deps = array(), $version = false, array $args = array() ) { 114 wp_script_modules()->enqueue( $id, $src, $deps, $version, $args ); 103 115 } 104 116 … … 170 182 } 171 183 184 // The Interactivity API is designed with server-side rendering as its primary goal, so all of its script modules should be loaded with low fetch priority since they should not be needed in the critical rendering path. 185 $args = array(); 186 if ( str_starts_with( $script_module_id, '@wordpress/interactivity' ) || str_starts_with( $script_module_id, '@wordpress/block-library' ) ) { 187 $args['fetchpriority'] = 'low'; 188 } 189 172 190 $path = includes_url( "js/dist/script-modules/{$file_name}" ); 173 wp_register_script_module( $script_module_id, $path, $script_module_data['dependencies'], $script_module_data['version'] );191 wp_register_script_module( $script_module_id, $path, $script_module_data['dependencies'], $script_module_data['version'], $args ); 174 192 } 175 193 } -
trunk/tests/phpunit/tests/dependencies/scripts.php
r60690 r60704 1128 1128 * Tests that dependents that are async but attached to a deferred main script, print with defer as opposed to async. 1129 1129 * 1130 * Also tests that fetchpriority attributes are added as expected. 1131 * 1130 1132 * @ticket 12009 1133 * @ticket 61734 1131 1134 * 1132 1135 * @covers WP_Scripts::do_item 1133 1136 * @covers WP_Scripts::get_eligible_loading_strategy 1137 * @covers ::wp_register_script 1134 1138 * @covers ::wp_enqueue_script 1135 1139 */ 1136 1140 public function test_defer_with_async_dependent() { 1137 1141 // case with one async dependent. 1138 wp_enqueue_script( 'main-script-d4', '/main-script-d4.js', array(), null, array( 'strategy' => 'defer' ) ); 1139 wp_enqueue_script( 'dependent-script-d4-1', '/dependent-script-d4-1.js', array( 'main-script-d4' ), null, array( 'strategy' => 'defer' ) ); 1140 wp_enqueue_script( 'dependent-script-d4-2', '/dependent-script-d4-2.js', array( 'dependent-script-d4-1' ), null, array( 'strategy' => 'async' ) ); 1141 wp_enqueue_script( 'dependent-script-d4-3', '/dependent-script-d4-3.js', array( 'dependent-script-d4-2' ), null, array( 'strategy' => 'defer' ) ); 1142 wp_register_script( 'main-script-d4', '/main-script-d4.js', array(), null, array( 'strategy' => 'defer' ) ); 1143 wp_enqueue_script( 1144 'dependent-script-d4-1', 1145 '/dependent-script-d4-1.js', 1146 array( 'main-script-d4' ), 1147 null, 1148 array( 1149 'strategy' => 'defer', 1150 'fetchpriority' => 'auto', 1151 ) 1152 ); 1153 wp_enqueue_script( 1154 'dependent-script-d4-2', 1155 '/dependent-script-d4-2.js', 1156 array( 'dependent-script-d4-1' ), 1157 null, 1158 array( 1159 'strategy' => 'async', 1160 'fetchpriority' => 'low', 1161 ) 1162 ); 1163 wp_enqueue_script( 1164 'dependent-script-d4-3', 1165 '/dependent-script-d4-3.js', 1166 array( 'dependent-script-d4-2' ), 1167 null, 1168 array( 1169 'strategy' => 'defer', 1170 'fetchpriority' => 'high', 1171 ) 1172 ); 1142 1173 $output = get_echo( 'wp_print_scripts' ); 1143 1174 $expected = "<script type='text/javascript' src='/main-script-d4.js' id='main-script-d4-js' defer='defer' data-wp-strategy='defer'></script>\n"; 1144 1175 $expected .= "<script type='text/javascript' src='/dependent-script-d4-1.js' id='dependent-script-d4-1-js' defer='defer' data-wp-strategy='defer'></script>\n"; 1145 $expected .= "<script type='text/javascript' src='/dependent-script-d4-2.js' id='dependent-script-d4-2-js' defer='defer' data-wp-strategy='async' ></script>\n";1146 $expected .= "<script type='text/javascript' src='/dependent-script-d4-3.js' id='dependent-script-d4-3-js' defer='defer' data-wp-strategy='defer' ></script>\n";1176 $expected .= "<script type='text/javascript' src='/dependent-script-d4-2.js' id='dependent-script-d4-2-js' defer='defer' data-wp-strategy='async' fetchpriority='low'></script>\n"; 1177 $expected .= "<script type='text/javascript' src='/dependent-script-d4-3.js' id='dependent-script-d4-3-js' defer='defer' data-wp-strategy='defer' fetchpriority='high'></script>\n"; 1147 1178 1148 1179 $this->assertEqualHTML( $expected, $output, '<body>', 'Scripts registered as defer but that have dependents that are async are expected to have said dependents deferred.' ); 1180 } 1181 1182 /** 1183 * Data provider for test_fetchpriority_values. 1184 * 1185 * @return array<string, array{fetchpriority: string}> 1186 */ 1187 public function data_provider_fetchpriority_values(): array { 1188 return array( 1189 'auto' => array( 'fetchpriority' => 'auto' ), 1190 'low' => array( 'fetchpriority' => 'low' ), 1191 'high' => array( 'fetchpriority' => 'high' ), 1192 ); 1193 } 1194 1195 /** 1196 * Tests that valid fetchpriority values are correctly added to script data. 1197 * 1198 * @ticket 61734 1199 * 1200 * @covers ::wp_register_script 1201 * @covers WP_Scripts::add_data 1202 * @covers ::wp_script_add_data 1203 * 1204 * @dataProvider data_provider_fetchpriority_values 1205 * 1206 * @param string $fetchpriority The fetchpriority value to test. 1207 */ 1208 public function test_fetchpriority_values( string $fetchpriority ) { 1209 wp_register_script( 'test-script', '/test-script.js', array(), null, array( 'fetchpriority' => $fetchpriority ) ); 1210 $this->assertArrayHasKey( 'fetchpriority', wp_scripts()->registered['test-script']->extra ); 1211 $this->assertSame( $fetchpriority, wp_scripts()->registered['test-script']->extra['fetchpriority'] ); 1212 1213 wp_register_script( 'test-script-2', '/test-script-2.js' ); 1214 $this->assertTrue( wp_script_add_data( 'test-script-2', 'fetchpriority', $fetchpriority ) ); 1215 $this->assertArrayHasKey( 'fetchpriority', wp_scripts()->registered['test-script-2']->extra ); 1216 $this->assertSame( $fetchpriority, wp_scripts()->registered['test-script-2']->extra['fetchpriority'] ); 1217 } 1218 1219 /** 1220 * Tests that an empty fetchpriority is treated the same as auto. 1221 * 1222 * @ticket 61734 1223 * 1224 * @covers ::wp_register_script 1225 * @covers WP_Scripts::add_data 1226 */ 1227 public function test_empty_fetchpriority_value() { 1228 wp_register_script( 'unset', '/joke.js', array(), null, array( 'fetchpriority' => 'low' ) ); 1229 $this->assertSame( 'low', wp_scripts()->registered['unset']->extra['fetchpriority'] ); 1230 $this->assertTrue( wp_script_add_data( 'unset', 'fetchpriority', null ) ); 1231 $this->assertSame( 'auto', wp_scripts()->registered['unset']->extra['fetchpriority'] ); 1232 } 1233 1234 /** 1235 * Tests that an invalid fetchpriority causes a _doing_it_wrong() warning. 1236 * 1237 * @ticket 61734 1238 * 1239 * @covers ::wp_register_script 1240 * @covers WP_Scripts::add_data 1241 * 1242 * @expectedIncorrectUsage WP_Scripts::add_data 1243 */ 1244 public function test_invalid_fetchpriority_value() { 1245 wp_register_script( 'joke', '/joke.js', array(), null, array( 'fetchpriority' => 'silly' ) ); 1246 $this->assertArrayNotHasKey( 'fetchpriority', wp_scripts()->registered['joke']->extra ); 1247 $this->assertArrayHasKey( 'WP_Scripts::add_data', $this->caught_doing_it_wrong ); 1248 $this->assertStringContainsString( 'Invalid fetchpriority `silly`', $this->caught_doing_it_wrong['WP_Scripts::add_data'] ); 1249 } 1250 1251 /** 1252 * Tests that an invalid fetchpriority causes a _doing_it_wrong() warning. 1253 * 1254 * @ticket 61734 1255 * 1256 * @covers ::wp_register_script 1257 * @covers WP_Scripts::add_data 1258 * 1259 * @expectedIncorrectUsage WP_Scripts::add_data 1260 */ 1261 public function test_invalid_fetchpriority_value_type() { 1262 wp_register_script( 'bad', '/bad.js' ); 1263 $this->assertFalse( wp_script_add_data( 'bad', 'fetchpriority', array( 'THIS IS SO WRONG!!!' ) ) ); 1264 $this->assertArrayNotHasKey( 'fetchpriority', wp_scripts()->registered['bad']->extra ); 1265 $this->assertArrayHasKey( 'WP_Scripts::add_data', $this->caught_doing_it_wrong ); 1266 $this->assertStringContainsString( 'Invalid fetchpriority `array`', $this->caught_doing_it_wrong['WP_Scripts::add_data'] ); 1267 } 1268 1269 /** 1270 * Tests that adding fetchpriority causes a _doing_it_wrong() warning on a script alias. 1271 * 1272 * @ticket 61734 1273 * 1274 * @covers ::wp_register_script 1275 * @covers WP_Scripts::add_data 1276 * 1277 * @expectedIncorrectUsage WP_Scripts::add_data 1278 */ 1279 public function test_invalid_fetchpriority_on_alias() { 1280 wp_register_script( 'alias', false, array(), null, array( 'fetchpriority' => 'low' ) ); 1281 $this->assertArrayNotHasKey( 'fetchpriority', wp_scripts()->registered['alias']->extra ); 1149 1282 } 1150 1283 -
trunk/tests/phpunit/tests/script-modules/wpScriptModules.php
r58952 r60704 9 9 * 10 10 * @group script-modules 11 *12 * @coversDefaultClass WP_Script_Modules13 11 */ 14 12 class Tests_Script_Modules_WpScriptModules extends WP_UnitTestCase { 15 13 16 14 /** 15 * @var WP_Script_Modules 16 */ 17 protected $original_script_modules; 18 19 /** 20 * @var string 21 */ 22 protected $original_wp_version; 23 24 /** 17 25 * Instance of WP_Script_Modules. 18 26 * … … 25 33 */ 26 34 public function set_up() { 35 global $wp_script_modules, $wp_version; 27 36 parent::set_up(); 28 // Set up the WP_Script_Modules instance. 29 $this->script_modules = new WP_Script_Modules(); 37 $this->original_script_modules = $wp_script_modules; 38 $this->original_wp_version = $wp_version; 39 $wp_script_modules = null; 40 $this->script_modules = wp_script_modules(); 41 } 42 43 /** 44 * Tear down. 45 */ 46 public function tear_down() { 47 global $wp_script_modules, $wp_version; 48 parent::tear_down(); 49 $wp_script_modules = $this->original_script_modules; 50 $wp_version = $this->original_wp_version; 30 51 } 31 52 … … 35 56 * @return array Enqueued script module URLs, keyed by script module identifier. 36 57 */ 37 public function get_enqueued_script_modules() { 38 $script_modules_markup = get_echo( array( $this->script_modules, 'print_enqueued_script_modules' ) ); 39 $p = new WP_HTML_Tag_Processor( $script_modules_markup ); 40 $enqueued_script_modules = array(); 41 58 public function get_enqueued_script_modules(): array { 59 $modules = array(); 60 61 $p = new WP_HTML_Tag_Processor( get_echo( array( $this->script_modules, 'print_enqueued_script_modules' ) ) ); 42 62 while ( $p->next_tag( array( 'tag' => 'SCRIPT' ) ) ) { 43 if ( 'module' === $p->get_attribute( 'type' ) ) { 44 $id = preg_replace( '/-js-module$/', '', $p->get_attribute( 'id' ) ); 45 $enqueued_script_modules[ $id ] = $p->get_attribute( 'src' ); 63 $this->assertSame( 'module', $p->get_attribute( 'type' ) ); 64 $this->assertIsString( $p->get_attribute( 'id' ) ); 65 $this->assertIsString( $p->get_attribute( 'src' ) ); 66 $this->assertStringEndsWith( '-js-module', $p->get_attribute( 'id' ) ); 67 68 $id = preg_replace( '/-js-module$/', '', (string) $p->get_attribute( 'id' ) ); 69 $fetchpriority = $p->get_attribute( 'fetchpriority' ); 70 $modules[ $id ] = array( 71 'url' => $p->get_attribute( 'src' ), 72 'fetchpriority' => is_string( $fetchpriority ) ? $fetchpriority : 'auto', 73 ); 74 } 75 76 return $modules; 77 } 78 79 /** 80 * Gets the script modules listed in the import map. 81 * 82 * @return array<string, string> Import map entry URLs, keyed by script module identifier. 83 */ 84 public function get_import_map(): array { 85 $p = new WP_HTML_Tag_Processor( get_echo( array( $this->script_modules, 'print_import_map' ) ) ); 86 if ( $p->next_tag( array( 'tag' => 'SCRIPT' ) ) ) { 87 $this->assertSame( 'importmap', $p->get_attribute( 'type' ) ); 88 $this->assertSame( 'wp-importmap', $p->get_attribute( 'id' ) ); 89 $data = json_decode( $p->get_modifiable_text(), true ); 90 $this->assertIsArray( $data ); 91 $this->assertArrayHasKey( 'imports', $data ); 92 return $data['imports']; 93 } else { 94 return array(); 95 } 96 } 97 98 /** 99 * Gets a list of preloaded script modules. 100 * 101 * @return array Preloaded script module URLs, keyed by script module identifier. 102 */ 103 public function get_preloaded_script_modules(): array { 104 $preloads = array(); 105 106 $p = new WP_HTML_Tag_Processor( get_echo( array( $this->script_modules, 'print_script_module_preloads' ) ) ); 107 while ( $p->next_tag( array( 'tag' => 'LINK' ) ) ) { 108 $this->assertSame( 'modulepreload', $p->get_attribute( 'rel' ) ); 109 $this->assertIsString( $p->get_attribute( 'id' ) ); 110 $this->assertIsString( $p->get_attribute( 'href' ) ); 111 $this->assertStringEndsWith( '-js-modulepreload', $p->get_attribute( 'id' ) ); 112 113 $id = preg_replace( '/-js-modulepreload$/', '', $p->get_attribute( 'id' ) ); 114 $fetchpriority = $p->get_attribute( 'fetchpriority' ); 115 $preloads[ $id ] = array( 116 'url' => $p->get_attribute( 'href' ), 117 'fetchpriority' => is_string( $fetchpriority ) ? $fetchpriority : 'auto', 118 ); 119 } 120 121 return $preloads; 122 } 123 124 /** 125 * Test wp_script_modules(). 126 * 127 * @covers ::wp_script_modules() 128 */ 129 public function test_wp_script_modules() { 130 $this->assertSame( $this->script_modules, wp_script_modules() ); 131 } 132 133 /** 134 * Tests various ways of registering, enqueueing, dequeuing, and deregistering a script module. 135 * 136 * This ensures that the global function aliases pass all the same parameters as the class methods. 137 * 138 * @ticket 56313 139 * 140 * @dataProvider data_test_register_and_enqueue_script_module 141 * 142 * @covers ::wp_register_script_module() 143 * @covers WP_Script_Modules::register() 144 * @covers ::wp_enqueue_script_module() 145 * @covers WP_Script_Modules::enqueue() 146 * @covers ::wp_dequeue_script_module() 147 * @covers WP_Script_Modules::dequeue() 148 * @covers ::wp_deregister_script_module() 149 * @covers WP_Script_Modules::deregister() 150 * @covers WP_Script_Modules::set_fetchpriority() 151 * @covers WP_Script_Modules::print_enqueued_script_modules() 152 * @covers WP_Script_Modules::print_import_map() 153 * @covers WP_Script_Modules::print_script_module_preloads() 154 */ 155 public function test_comprehensive_methods( bool $use_global_function, bool $only_enqueue ) { 156 global $wp_version; 157 $wp_version = '99.9.9'; 158 159 $register = static function ( ...$args ) use ( $use_global_function ) { 160 if ( $use_global_function ) { 161 wp_register_script_module( ...$args ); 162 } else { 163 wp_script_modules()->register( ...$args ); 164 } 165 }; 166 167 $register_and_enqueue = static function ( ...$args ) use ( $use_global_function, $only_enqueue ) { 168 if ( $use_global_function ) { 169 if ( $only_enqueue ) { 170 wp_enqueue_script_module( ...$args ); 171 } else { 172 wp_register_script_module( ...$args ); 173 wp_enqueue_script_module( $args[0] ); 174 } 175 } else { 176 if ( $only_enqueue ) { 177 wp_script_modules()->enqueue( ...$args ); 178 } else { 179 wp_script_modules()->register( ...$args ); 180 wp_script_modules()->enqueue( $args[0] ); 181 } 182 } 183 }; 184 185 // Minimal args. 186 $register_and_enqueue( 'a', '/a.js' ); 187 188 // One Dependency. 189 $register( 'b-dep', '/b-dep.js' ); 190 $register_and_enqueue( 'b', '/b.js', array( 'b-dep' ) ); 191 $this->assertTrue( wp_script_modules()->set_fetchpriority( 'b', 'low' ) ); 192 193 // Two dependencies with different formats and a false version. 194 $register( 'c-dep', '/c-static.js', array(), false, array( 'fetchpriority' => 'low' ) ); 195 $register( 'c-static-dep', '/c-static-dep.js', array(), false, array( 'fetchpriority' => 'high' ) ); 196 $register_and_enqueue( 197 'c', 198 '/c.js', 199 array( 200 'c-dep', 201 array( 202 'id' => 'c-static-dep', 203 'import' => 'static', 204 ), 205 ), 206 false 207 ); 208 209 // Two dependencies, one imported statically and the other dynamically, with a null version. 210 $register( 'd-static-dep', '/d-static-dep.js', array(), false, array( 'fetchpriority' => 'auto' ) ); 211 $register( 'd-dynamic-dep', '/d-dynamic-dep.js', array(), false, array( 'fetchpriority' => 'high' ) ); // Because this is a dynamic import dependency, the fetchpriority will not be reflected in the markup since no SCRIPT tag and no preload LINK are printed, and the importmap SCRIPT does not support designating a priority. 212 $register_and_enqueue( 213 'd', 214 '/d.js', 215 array( 216 array( 217 'id' => 'd-static-dep', 218 'import' => 'static', 219 ), 220 array( 221 'id' => 'd-dynamic-dep', 222 'import' => 'dynamic', 223 ), 224 ), 225 null 226 ); 227 228 // No dependencies, with a string version version. 229 $register_and_enqueue( 230 'e', 231 '/e.js', 232 array(), 233 '1.0.0' 234 ); 235 236 // No dependencies, with a string version and fetch priority. 237 $register_and_enqueue( 238 'f', 239 '/f.js', 240 array(), 241 '2.0.0', 242 array( 'fetchpriority' => 'auto' ) 243 ); 244 245 // No dependencies, with a string version and fetch priority of low. 246 $register_and_enqueue( 247 'g', 248 '/g.js', 249 array(), 250 '2.0.0', 251 array( 'fetchpriority' => 'low' ) 252 ); 253 254 // No dependencies, with a string version and fetch priority of high. 255 $register_and_enqueue( 256 'h', 257 '/h.js', 258 array(), 259 '3.0.0', 260 array( 'fetchpriority' => 'high' ) 261 ); 262 263 $actual = array( 264 'preload_links' => $this->get_preloaded_script_modules(), 265 'script_tags' => $this->get_enqueued_script_modules(), 266 'import_map' => $this->get_import_map(), 267 ); 268 269 $this->assertSame( 270 array( 271 'preload_links' => array( 272 'b-dep' => array( 273 'url' => '/b-dep.js?ver=99.9.9', 274 'fetchpriority' => 'auto', 275 ), 276 'c-dep' => array( 277 'url' => '/c-static.js?ver=99.9.9', 278 'fetchpriority' => 'low', 279 ), 280 'c-static-dep' => array( 281 'url' => '/c-static-dep.js?ver=99.9.9', 282 'fetchpriority' => 'high', 283 ), 284 'd-static-dep' => array( 285 'url' => '/d-static-dep.js?ver=99.9.9', 286 'fetchpriority' => 'auto', 287 ), 288 ), 289 'script_tags' => array( 290 'a' => array( 291 'url' => '/a.js?ver=99.9.9', 292 'fetchpriority' => 'auto', 293 ), 294 'b' => array( 295 'url' => '/b.js?ver=99.9.9', 296 'fetchpriority' => 'low', 297 ), 298 'c' => array( 299 'url' => '/c.js?ver=99.9.9', 300 'fetchpriority' => 'auto', 301 ), 302 'd' => array( 303 'url' => '/d.js', 304 'fetchpriority' => 'auto', 305 ), 306 'e' => array( 307 'url' => '/e.js?ver=1.0.0', 308 'fetchpriority' => 'auto', 309 ), 310 'f' => array( 311 'url' => '/f.js?ver=2.0.0', 312 'fetchpriority' => 'auto', 313 ), 314 'g' => array( 315 'url' => '/g.js?ver=2.0.0', 316 'fetchpriority' => 'low', 317 ), 318 'h' => array( 319 'url' => '/h.js?ver=3.0.0', 320 'fetchpriority' => 'high', 321 ), 322 ), 323 'import_map' => array( 324 'b-dep' => '/b-dep.js?ver=99.9.9', 325 'c-dep' => '/c-static.js?ver=99.9.9', 326 'c-static-dep' => '/c-static-dep.js?ver=99.9.9', 327 'd-static-dep' => '/d-static-dep.js?ver=99.9.9', 328 'd-dynamic-dep' => '/d-dynamic-dep.js?ver=99.9.9', 329 ), 330 ), 331 $actual, 332 "Snapshot:\n" . var_export( $actual, true ) 333 ); 334 335 // Dequeue the first half of the scripts. 336 foreach ( array( 'a', 'b', 'c', 'd' ) as $id ) { 337 if ( $use_global_function ) { 338 wp_dequeue_script_module( $id ); 339 } else { 340 wp_script_modules()->dequeue( $id ); 46 341 } 47 342 } 48 343 49 return $enqueued_script_modules; 50 } 51 52 /** 53 * Gets the script modules listed in the import map. 54 * 55 * @return array Import map entry URLs, keyed by script module identifier. 56 */ 57 public function get_import_map() { 58 $import_map_markup = get_echo( array( $this->script_modules, 'print_import_map' ) ); 59 preg_match( '/<script type="importmap" id="wp-importmap">.*?(\{.*\}).*?<\/script>/s', $import_map_markup, $import_map_string ); 60 return json_decode( $import_map_string[1], true )['imports']; 61 } 62 63 /** 64 * Gets a list of preloaded script modules. 65 * 66 * @return array Preloaded script module URLs, keyed by script module identifier. 67 */ 68 public function get_preloaded_script_modules() { 69 $preloaded_markup = get_echo( array( $this->script_modules, 'print_script_module_preloads' ) ); 70 $p = new WP_HTML_Tag_Processor( $preloaded_markup ); 71 $preloaded_script_modules = array(); 72 73 while ( $p->next_tag( array( 'tag' => 'LINK' ) ) ) { 74 if ( 'modulepreload' === $p->get_attribute( 'rel' ) ) { 75 $id = preg_replace( '/-js-modulepreload$/', '', $p->get_attribute( 'id' ) ); 76 $preloaded_script_modules[ $id ] = $p->get_attribute( 'href' ); 344 $actual = array( 345 'preload_links' => $this->get_preloaded_script_modules(), 346 'script_tags' => $this->get_enqueued_script_modules(), 347 'import_map' => $this->get_import_map(), 348 ); 349 $this->assertSame( 350 array( 351 'preload_links' => array(), 352 'script_tags' => array( 353 'e' => array( 354 'url' => '/e.js?ver=1.0.0', 355 'fetchpriority' => 'auto', 356 ), 357 'f' => array( 358 'url' => '/f.js?ver=2.0.0', 359 'fetchpriority' => 'auto', 360 ), 361 'g' => array( 362 'url' => '/g.js?ver=2.0.0', 363 'fetchpriority' => 'low', 364 ), 365 'h' => array( 366 'url' => '/h.js?ver=3.0.0', 367 'fetchpriority' => 'high', 368 ), 369 ), 370 'import_map' => array(), 371 ), 372 $actual, 373 "Snapshot:\n" . var_export( $actual, true ) 374 ); 375 376 // Unregister the remaining scripts. 377 foreach ( array( 'e', 'f', 'g', 'h' ) as $id ) { 378 if ( $use_global_function ) { 379 wp_dequeue_script_module( $id ); 380 } else { 381 wp_script_modules()->dequeue( $id ); 77 382 } 78 383 } 79 384 80 return $preloaded_script_modules; 385 $actual = array( 386 'preload_links' => $this->get_preloaded_script_modules(), 387 'script_tags' => $this->get_enqueued_script_modules(), 388 'import_map' => $this->get_import_map(), 389 ); 390 $this->assertSame( 391 array( 392 'preload_links' => array(), 393 'script_tags' => array(), 394 'import_map' => array(), 395 ), 396 $actual, 397 "Snapshot:\n" . var_export( $actual, true ) 398 ); 399 } 400 401 /** 402 * Data provider. 403 * 404 * @return array<string, array{ use_global_function: bool, only_enqueue: bool }> 405 */ 406 public function data_test_register_and_enqueue_script_module(): array { 407 $data = array(); 408 409 foreach ( array( true, false ) as $use_global_function ) { 410 foreach ( array( true, false ) as $only_enqueue ) { 411 $test_case = compact( 'use_global_function', 'only_enqueue' ); 412 $key_parts = array(); 413 foreach ( $test_case as $param_name => $param_value ) { 414 $key_parts[] = sprintf( '%s_%s', $param_name, json_encode( $param_value ) ); 415 } 416 $data[ join( '_', $key_parts ) ] = $test_case; 417 } 418 } 419 420 return $data; 81 421 } 82 422 … … 86 426 * @ticket 56313 87 427 * 88 * @covers ::register() 89 * @covers ::enqueue() 90 * @covers ::print_enqueued_script_modules() 428 * @covers WP_Script_Modules::register() 429 * @covers WP_Script_Modules::enqueue() 430 * @covers WP_Script_Modules::print_enqueued_script_modules() 431 * @covers WP_Script_Modules::set_fetchpriority() 91 432 */ 92 433 public function test_wp_enqueue_script_module() { 93 434 $this->script_modules->register( 'foo', '/foo.js' ); 94 $this->script_modules->register( 'bar', '/bar.js' ); 435 $this->script_modules->register( 'bar', '/bar.js', array(), false, array( 'fetchpriority' => 'high' ) ); 436 $this->script_modules->register( 'baz', '/baz.js' ); 437 $this->assertTrue( $this->script_modules->set_fetchpriority( 'baz', 'low' ) ); 95 438 $this->script_modules->enqueue( 'foo' ); 96 439 $this->script_modules->enqueue( 'bar' ); 440 $this->script_modules->enqueue( 'baz' ); 97 441 98 442 $enqueued_script_modules = $this->get_enqueued_script_modules(); 99 443 100 $this->assertCount( 2, $enqueued_script_modules ); 101 $this->assertStringStartsWith( '/foo.js', $enqueued_script_modules['foo'] ); 102 $this->assertStringStartsWith( '/bar.js', $enqueued_script_modules['bar'] ); 444 $this->assertCount( 3, $enqueued_script_modules ); 445 $this->assertStringStartsWith( '/foo.js', $enqueued_script_modules['foo']['url'] ); 446 $this->assertSame( 'auto', $enqueued_script_modules['foo']['fetchpriority'] ); 447 $this->assertStringStartsWith( '/bar.js', $enqueued_script_modules['bar']['url'] ); 448 $this->assertSame( 'high', $enqueued_script_modules['bar']['fetchpriority'] ); 449 $this->assertStringStartsWith( '/baz.js', $enqueued_script_modules['baz']['url'] ); 450 $this->assertSame( 'low', $enqueued_script_modules['baz']['fetchpriority'] ); 103 451 } 104 452 … … 108 456 * @ticket 56313 109 457 * 110 * @covers ::register()111 * @covers ::enqueue()112 * @covers ::dequeue()113 * @covers ::print_enqueued_script_modules()458 * @covers WP_Script_Modules::register() 459 * @covers WP_Script_Modules::enqueue() 460 * @covers WP_Script_Modules::dequeue() 461 * @covers WP_Script_Modules::print_enqueued_script_modules() 114 462 */ 115 463 public function test_wp_dequeue_script_module() { … … 135 483 * @ticket 60463 136 484 * 137 * @covers ::register()138 * @covers ::enqueue()139 * @covers ::deregister()140 * @covers ::get_enqueued_script_modules()485 * @covers WP_Script_Modules::register() 486 * @covers WP_Script_Modules::enqueue() 487 * @covers WP_Script_Modules::deregister() 488 * @covers WP_Script_Modules::get_enqueued_script_modules() 141 489 */ 142 490 public function test_wp_deregister_script_module() { … … 161 509 * @ticket 60463 162 510 * 163 * @covers ::deregister()164 * @covers ::get_enqueued_script_modules()511 * @covers WP_Script_Modules::deregister() 512 * @covers WP_Script_Modules::get_enqueued_script_modules() 165 513 */ 166 514 public function test_wp_deregister_unexistent_script_module() { … … 179 527 * @ticket 60463 180 528 * 181 * @covers ::get_enqueued_script_modules()182 * @covers ::register()183 * @covers ::deregister()184 * @covers ::enqueue()529 * @covers WP_Script_Modules::get_enqueued_script_modules() 530 * @covers WP_Script_Modules::register() 531 * @covers WP_Script_Modules::deregister() 532 * @covers WP_Script_Modules::enqueue() 185 533 */ 186 534 public function test_wp_deregister_already_deregistered_script_module() { … … 206 554 * @ticket 56313 207 555 * 208 * @covers ::register()209 * @covers ::enqueue()210 * @covers ::print_enqueued_script_modules()556 * @covers WP_Script_Modules::register() 557 * @covers WP_Script_Modules::enqueue() 558 * @covers WP_Script_Modules::print_enqueued_script_modules() 211 559 */ 212 560 public function test_wp_enqueue_script_module_works_before_register() { … … 218 566 219 567 $this->assertCount( 1, $enqueued_script_modules ); 220 $this->assertStringStartsWith( '/foo.js', $enqueued_script_modules['foo'] ); 568 $this->assertStringStartsWith( '/foo.js', $enqueued_script_modules['foo']['url'] ); 569 $this->assertSame( 'auto', $enqueued_script_modules['foo']['fetchpriority'] ); 221 570 $this->assertArrayNotHasKey( 'bar', $enqueued_script_modules ); 222 571 } … … 228 577 * @ticket 56313 229 578 * 230 * @covers ::register()231 * @covers ::enqueue()232 * @covers ::dequeue()233 * @covers ::print_enqueued_script_modules()579 * @covers WP_Script_Modules::register() 580 * @covers WP_Script_Modules::enqueue() 581 * @covers WP_Script_Modules::dequeue() 582 * @covers WP_Script_Modules::print_enqueued_script_modules() 234 583 */ 235 584 public function test_wp_dequeue_script_module_works_before_register() { … … 253 602 * @ticket 56313 254 603 * 255 * @covers ::register()256 * @covers ::enqueue()257 * @covers ::print_import_map()604 * @covers WP_Script_Modules::register() 605 * @covers WP_Script_Modules::enqueue() 606 * @covers WP_Script_Modules::print_import_map() 258 607 */ 259 608 public function test_wp_import_map_dependencies() { … … 276 625 * @ticket 56313 277 626 * 278 * @covers ::register()279 * @covers ::enqueue()280 * @covers ::print_import_map()627 * @covers WP_Script_Modules::register() 628 * @covers WP_Script_Modules::enqueue() 629 * @covers WP_Script_Modules::print_import_map() 281 630 */ 282 631 public function test_wp_import_map_no_duplicate_dependencies() { … … 299 648 * @ticket 56313 300 649 * 301 * @covers ::register()302 * @covers ::enqueue()303 * @covers ::print_import_map()650 * @covers WP_Script_Modules::register() 651 * @covers WP_Script_Modules::enqueue() 652 * @covers WP_Script_Modules::print_import_map() 304 653 */ 305 654 public function test_wp_import_map_recursive_dependencies() { … … 350 699 * @ticket 56313 351 700 * 352 * @covers ::register()353 * @covers ::enqueue()354 * @covers ::print_import_map()701 * @covers WP_Script_Modules::register() 702 * @covers WP_Script_Modules::enqueue() 703 * @covers WP_Script_Modules::print_import_map() 355 704 */ 356 705 public function test_wp_import_map_doesnt_print_if_no_dependencies() { … … 369 718 * @ticket 56313 370 719 * 371 * @covers ::register()372 * @covers ::enqueue()373 * @covers ::print_script_module_preloads()720 * @covers WP_Script_Modules::register() 721 * @covers WP_Script_Modules::enqueue() 722 * @covers WP_Script_Modules::print_script_module_preloads() 374 723 */ 375 724 public function test_wp_enqueue_preloaded_static_dependencies() { … … 397 746 'import' => 'dynamic', 398 747 ), 399 ) 748 ), 749 false, 750 array( 'fetchpriority' => 'high' ) 400 751 ); 401 752 $this->script_modules->register( 'dynamic-dep', '/dynamic-dep.js' ); … … 408 759 409 760 $this->assertCount( 2, $preloaded_script_modules ); 410 $this->assertStringStartsWith( '/static-dep.js', $preloaded_script_modules['static-dep'] ); 411 $this->assertStringStartsWith( '/nested-static-dep.js', $preloaded_script_modules['nested-static-dep'] ); 761 $this->assertStringStartsWith( '/static-dep.js', $preloaded_script_modules['static-dep']['url'] ); 762 $this->assertSame( 'high', $preloaded_script_modules['static-dep']['fetchpriority'] ); 763 $this->assertStringStartsWith( '/nested-static-dep.js', $preloaded_script_modules['nested-static-dep']['url'] ); 764 $this->assertSame( 'auto', $preloaded_script_modules['nested-static-dep']['fetchpriority'] ); 412 765 $this->assertArrayNotHasKey( 'dynamic-dep', $preloaded_script_modules ); 413 766 $this->assertArrayNotHasKey( 'nested-dynamic-dep', $preloaded_script_modules ); … … 420 773 * @ticket 56313 421 774 * 422 * @covers ::register()423 * @covers ::enqueue()424 * @covers ::print_script_module_preloads()775 * @covers WP_Script_Modules::register() 776 * @covers WP_Script_Modules::enqueue() 777 * @covers WP_Script_Modules::print_script_module_preloads() 425 778 */ 426 779 public function test_wp_dont_preload_static_dependencies_of_dynamic_dependencies() { … … 445 798 446 799 $this->assertCount( 1, $preloaded_script_modules ); 447 $this->assertStringStartsWith( '/static-dep.js', $preloaded_script_modules['static-dep'] ); 800 $this->assertStringStartsWith( '/static-dep.js', $preloaded_script_modules['static-dep']['url'] ); 801 $this->assertSame( 'auto', $preloaded_script_modules['static-dep']['fetchpriority'] ); 448 802 $this->assertArrayNotHasKey( 'dynamic-dep', $preloaded_script_modules ); 449 803 $this->assertArrayNotHasKey( 'nested-dynamic-dep', $preloaded_script_modules ); … … 456 810 * @ticket 56313 457 811 * 458 * @covers ::register()459 * @covers ::enqueue()460 * @covers ::print_script_module_preloads()812 * @covers WP_Script_Modules::register() 813 * @covers WP_Script_Modules::enqueue() 814 * @covers WP_Script_Modules::print_script_module_preloads() 461 815 */ 462 816 public function test_wp_preloaded_dependencies_filter_enqueued_script_modules() { … … 487 841 * @ticket 56313 488 842 * 489 * @covers ::register()490 * @covers ::enqueue()491 * @covers ::print_import_map()843 * @covers WP_Script_Modules::register() 844 * @covers WP_Script_Modules::enqueue() 845 * @covers WP_Script_Modules::print_import_map() 492 846 */ 493 847 public function test_wp_enqueued_script_modules_with_dependants_add_import_map() { … … 518 872 * @ticket 56313 519 873 * 520 * @covers ::get_src()874 * @covers WP_Script_Modules::get_src() 521 875 */ 522 876 public function test_get_src() { … … 587 941 * @ticket 56313 588 942 * 589 * @covers ::register()590 * @covers ::enqueue()591 * @covers ::print_enqueued_script_modules()592 * @covers ::print_import_map()593 * @covers ::print_script_module_preloads()594 * @covers ::get_version_query_string()943 * @covers WP_Script_Modules::register() 944 * @covers WP_Script_Modules::enqueue() 945 * @covers WP_Script_Modules::print_enqueued_script_modules() 946 * @covers WP_Script_Modules::print_import_map() 947 * @covers WP_Script_Modules::print_script_module_preloads() 948 * @covers WP_Script_Modules::get_version_query_string() 595 949 */ 596 950 public function test_version_is_propagated_correctly() { … … 601 955 'dep', 602 956 ), 603 '1.0' 604 ); 605 $this->script_modules->register( 'dep', '/dep.js', array(), '2.0' ); 957 '1.0', 958 array( 'fetchpriority' => 'auto' ) 959 ); 960 $this->script_modules->register( 'dep', '/dep.js', array(), '2.0', array( 'fetchpriority' => 'high' ) ); 606 961 $this->script_modules->enqueue( 'foo' ); 607 962 608 963 $enqueued_script_modules = $this->get_enqueued_script_modules(); 609 $this->assertSame( '/foo.js?ver=1.0', $enqueued_script_modules['foo'] ); 964 $this->assertSame( '/foo.js?ver=1.0', $enqueued_script_modules['foo']['url'] ); 965 $this->assertSame( 'auto', $enqueued_script_modules['foo']['fetchpriority'] ); 610 966 611 967 $import_map = $this->get_import_map(); … … 613 969 614 970 $preloaded_script_modules = $this->get_preloaded_script_modules(); 615 $this->assertSame( '/dep.js?ver=2.0', $preloaded_script_modules['dep'] ); 971 $this->assertSame( '/dep.js?ver=2.0', $preloaded_script_modules['dep']['url'] ); 972 $this->assertSame( 'high', $preloaded_script_modules['dep']['fetchpriority'] ); 616 973 } 617 974 … … 622 979 * @ticket 56313 623 980 * 624 * @covers ::enqueue()625 * @covers ::print_enqueued_script_modules()981 * @covers WP_Script_Modules::enqueue() 982 * @covers WP_Script_Modules::print_enqueued_script_modules() 626 983 */ 627 984 public function test_wp_enqueue_script_module_doesnt_register_without_a_valid_src() { … … 640 997 * @ticket 56313 641 998 * 642 * @covers ::enqueue()643 * @covers ::print_enqueued_script_modules()999 * @covers WP_Script_Modules::enqueue() 1000 * @covers WP_Script_Modules::print_enqueued_script_modules() 644 1001 */ 645 1002 public function test_wp_enqueue_script_module_registers_with_valid_src() { … … 649 1006 650 1007 $this->assertCount( 1, $enqueued_script_modules ); 651 $this->assertStringStartsWith( '/foo.js', $enqueued_script_modules['foo'] ); 1008 $this->assertStringStartsWith( '/foo.js', $enqueued_script_modules['foo']['url'] ); 1009 $this->assertSame( 'auto', $enqueued_script_modules['foo']['fetchpriority'] ); 652 1010 } 653 1011 … … 658 1016 * @ticket 56313 659 1017 * 660 * @covers ::enqueue()661 * @covers ::print_enqueued_script_modules()1018 * @covers WP_Script_Modules::enqueue() 1019 * @covers WP_Script_Modules::print_enqueued_script_modules() 662 1020 */ 663 1021 public function test_wp_enqueue_script_module_registers_with_valid_src_the_second_time() { … … 674 1032 675 1033 $this->assertCount( 1, $enqueued_script_modules ); 676 $this->assertStringStartsWith( '/foo.js', $enqueued_script_modules['foo'] ); 1034 $this->assertStringStartsWith( '/foo.js', $enqueued_script_modules['foo']['url'] ); 1035 $this->assertSame( 'auto', $enqueued_script_modules['foo']['fetchpriority'] ); 677 1036 } 678 1037 … … 683 1042 * @ticket 56313 684 1043 * 685 * @covers ::register()686 * @covers ::enqueue()687 * @covers ::print_enqueued_script_modules()688 * @covers ::print_import_map()1044 * @covers WP_Script_Modules::register() 1045 * @covers WP_Script_Modules::enqueue() 1046 * @covers WP_Script_Modules::print_enqueued_script_modules() 1047 * @covers WP_Script_Modules::print_import_map() 689 1048 */ 690 1049 public function test_wp_enqueue_script_module_registers_all_params() { 691 $this->script_modules->enqueue( 'foo', '/foo.js', array( 'dep' ), '1.0' );1050 $this->script_modules->enqueue( 'foo', '/foo.js', array( 'dep' ), '1.0', array( 'fetchpriority' => 'low' ) ); 692 1051 $this->script_modules->register( 'dep', '/dep.js' ); 693 1052 … … 696 1055 697 1056 $this->assertCount( 1, $enqueued_script_modules ); 698 $this->assertSame( '/foo.js?ver=1.0', $enqueued_script_modules['foo'] ); 1057 $this->assertSame( '/foo.js?ver=1.0', $enqueued_script_modules['foo']['url'] ); 1058 $this->assertSame( 'low', $enqueued_script_modules['foo']['fetchpriority'] ); 699 1059 $this->assertCount( 1, $import_map ); 700 1060 $this->assertStringStartsWith( '/dep.js', $import_map['dep'] ); … … 853 1213 854 1214 // Non UTF-8 855 'Solidus '=> array( '/', '/', 'iso-8859-1' ),856 'Less than '=> array( '<', '\u003C', 'iso-8859-1' ),857 'Greater than '=> array( '>', '\u003E', 'iso-8859-1' ),858 'Ampersand '=> array( '&', '&', 'iso-8859-1' ),859 'Newline '=> array( "\n", "\\n", 'iso-8859-1' ),860 'Tab '=> array( "\t", "\\t", 'iso-8859-1' ),861 'Form feed '=> array( "\f", "\\f", 'iso-8859-1' ),862 'Carriage return '=> array( "\r", "\\r", 'iso-8859-1' ),863 'Line separator '=> array( "\u{2028}", "\u2028", 'iso-8859-1' ),864 'Paragraph separator '=> array( "\u{2029}", "\u2029", 'iso-8859-1' ),1215 'Solidus non-utf8' => array( '/', '/', 'iso-8859-1' ), 1216 'Less than non-utf8' => array( '<', '\u003C', 'iso-8859-1' ), 1217 'Greater than non-utf8' => array( '>', '\u003E', 'iso-8859-1' ), 1218 'Ampersand non-utf8' => array( '&', '&', 'iso-8859-1' ), 1219 'Newline non-utf8' => array( "\n", "\\n", 'iso-8859-1' ), 1220 'Tab non-utf8' => array( "\t", "\\t", 'iso-8859-1' ), 1221 'Form feed non-utf8' => array( "\f", "\\f", 'iso-8859-1' ), 1222 'Carriage return non-utf8' => array( "\r", "\\r", 'iso-8859-1' ), 1223 'Line separator non-utf8' => array( "\u{2028}", "\u2028", 'iso-8859-1' ), 1224 'Paragraph separator non-utf8' => array( "\u{2029}", "\u2029", 'iso-8859-1' ), 865 1225 /* 866 1226 * The following is the Flag of England emoji 867 1227 * PHP: "\u{1F3F4}\u{E0067}\u{E0062}\u{E0065}\u{E006E}\u{E0067}\u{E007F}" 868 1228 */ 869 'Flag of england '=> array( '🏴', "\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f", 'iso-8859-1' ),870 'Malicious script closer '=> array( '</script>', '\u003C/script\u003E', 'iso-8859-1' ),871 'Entity-encoded malicious script closer ' => array( '</script>', '</script>', 'iso-8859-1' ),1229 'Flag of england non-utf8' => array( '🏴', "\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f", 'iso-8859-1' ), 1230 'Malicious script closer non-utf8' => array( '</script>', '\u003C/script\u003E', 'iso-8859-1' ), 1231 'Entity-encoded malicious script closer non-utf8' => array( '</script>', '</script>', 'iso-8859-1' ), 872 1232 873 1233 ); … … 895 1255 896 1256 /** 1257 * Data provider for test_fetchpriority_values. 1258 * 1259 * @return array<string, array{fetchpriority: string}> 1260 */ 1261 public function data_provider_fetchpriority_values(): array { 1262 return array( 1263 'auto' => array( 'fetchpriority' => 'auto' ), 1264 'low' => array( 'fetchpriority' => 'low' ), 1265 'high' => array( 'fetchpriority' => 'high' ), 1266 ); 1267 } 1268 1269 /** 1270 * Tests that valid fetchpriority values are correctly added to the registered module. 1271 * 1272 * @ticket 61734 1273 * 1274 * @covers WP_Script_Modules::register 1275 * @covers WP_Script_Modules::set_fetchpriority 1276 * 1277 * @dataProvider data_provider_fetchpriority_values 1278 * 1279 * @param string $fetchpriority The fetchpriority value to test. 1280 */ 1281 public function test_fetchpriority_values( string $fetchpriority ) { 1282 $this->script_modules->register( 'test-script', '/test-script.js', array(), null, array( 'fetchpriority' => $fetchpriority ) ); 1283 $registered_modules = $this->get_registered_script_modules( $this->script_modules ); 1284 $this->assertSame( $fetchpriority, $registered_modules['test-script']['fetchpriority'] ); 1285 1286 $this->script_modules->register( 'test-script-2', '/test-script-2.js' ); 1287 $this->assertTrue( $this->script_modules->set_fetchpriority( 'test-script-2', $fetchpriority ) ); 1288 $registered_modules = $this->get_registered_script_modules( $this->script_modules ); 1289 $this->assertSame( $fetchpriority, $registered_modules['test-script-2']['fetchpriority'] ); 1290 1291 $this->assertTrue( $this->script_modules->set_fetchpriority( 'test-script-2', '' ) ); 1292 $registered_modules = $this->get_registered_script_modules( $this->script_modules ); 1293 $this->assertSame( 'auto', $registered_modules['test-script-2']['fetchpriority'] ); 1294 } 1295 1296 /** 1297 * Tests that a script module with an invalid fetchpriority value gets a value of auto. 1298 * 1299 * @ticket 61734 1300 * 1301 * @covers WP_Script_Modules::register 1302 * @expectedIncorrectUsage WP_Script_Modules::register 1303 */ 1304 public function test_register_script_module_having_fetchpriority_with_invalid_value() { 1305 $this->script_modules->register( 'foo', '/foo.js', array(), false, array( 'fetchpriority' => 'silly' ) ); 1306 $registered_modules = $this->get_registered_script_modules( $this->script_modules ); 1307 $this->assertSame( 'auto', $registered_modules['foo']['fetchpriority'] ); 1308 $this->assertArrayHasKey( 'WP_Script_Modules::register', $this->caught_doing_it_wrong ); 1309 $this->assertStringContainsString( 'Invalid fetchpriority `silly`', $this->caught_doing_it_wrong['WP_Script_Modules::register'] ); 1310 } 1311 1312 /** 1313 * Tests that a script module with an invalid fetchpriority value type gets a value of auto. 1314 * 1315 * @ticket 61734 1316 * 1317 * @covers WP_Script_Modules::register 1318 * @expectedIncorrectUsage WP_Script_Modules::register 1319 */ 1320 public function test_register_script_module_having_fetchpriority_with_invalid_value_type() { 1321 $this->script_modules->register( 'foo', '/foo.js', array(), false, array( 'fetchpriority' => array( 'WHY AM I NOT A STRING???' ) ) ); 1322 $registered_modules = $this->get_registered_script_modules( $this->script_modules ); 1323 $this->assertSame( 'auto', $registered_modules['foo']['fetchpriority'] ); 1324 $this->assertArrayHasKey( 'WP_Script_Modules::register', $this->caught_doing_it_wrong ); 1325 $this->assertStringContainsString( 'Invalid fetchpriority `array`', $this->caught_doing_it_wrong['WP_Script_Modules::register'] ); 1326 } 1327 1328 /** 1329 * Tests that a setting the fetchpriority for script module with an invalid value is ignored so that it remains auto. 1330 * 1331 * @ticket 61734 1332 * 1333 * @covers WP_Script_Modules::register 1334 * @covers WP_Script_Modules::set_fetchpriority 1335 * @expectedIncorrectUsage WP_Script_Modules::set_fetchpriority 1336 */ 1337 public function test_set_fetchpriority_with_invalid_value() { 1338 $this->script_modules->register( 'foo', '/foo.js' ); 1339 $this->script_modules->set_fetchpriority( 'foo', 'silly' ); 1340 $registered_modules = $this->get_registered_script_modules( $this->script_modules ); 1341 $this->assertSame( 'auto', $registered_modules['foo']['fetchpriority'] ); 1342 } 1343 1344 /** 1345 * Gets registered script modules. 1346 * 1347 * @param WP_Script_Modules $script_modules 1348 * @return array<string, array> Registered modules. 1349 */ 1350 private function get_registered_script_modules( WP_Script_Modules $script_modules ): array { 1351 $reflection_class = new ReflectionClass( $script_modules ); 1352 $registered_property = $reflection_class->getProperty( 'registered' ); 1353 $registered_property->setAccessible( true ); 1354 return $registered_property->getValue( $script_modules ); 1355 } 1356 1357 /** 897 1358 * Data provider. 898 1359 *
Note: See TracChangeset
for help on using the changeset viewer.