[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * WordPress scripts and styles default loader. 4 * 5 * Several constants are used to manage the loading, concatenating and compression of scripts and CSS: 6 * define('SCRIPT_DEBUG', true); loads the development (non-minified) versions of all scripts and CSS, and disables compression and concatenation, 7 * define('CONCATENATE_SCRIPTS', false); disables compression and concatenation of scripts and CSS, 8 * define('COMPRESS_SCRIPTS', false); disables compression of scripts, 9 * define('COMPRESS_CSS', false); disables compression of CSS, 10 * define('ENFORCE_GZIP', true); forces gzip for compression (default is deflate). 11 * 12 * The globals $concatenate_scripts, $compress_scripts and $compress_css can be set by plugins 13 * to temporarily override the above settings. Also a compression test is run once and the result is saved 14 * as option 'can_compress_scripts' (0/1). The test will run again if that option is deleted. 15 * 16 * @package WordPress 17 */ 18 19 /** WordPress Dependency Class */ 20 require ABSPATH . WPINC . '/class-wp-dependency.php'; 21 22 /** WordPress Dependencies Class */ 23 require ABSPATH . WPINC . '/class-wp-dependencies.php'; 24 25 /** WordPress Scripts Class */ 26 require ABSPATH . WPINC . '/class-wp-scripts.php'; 27 28 /** WordPress Scripts Functions */ 29 require ABSPATH . WPINC . '/functions.wp-scripts.php'; 30 31 /** WordPress Styles Class */ 32 require ABSPATH . WPINC . '/class-wp-styles.php'; 33 34 /** WordPress Styles Functions */ 35 require ABSPATH . WPINC . '/functions.wp-styles.php'; 36 37 /** 38 * Registers TinyMCE scripts. 39 * 40 * @since 5.0.0 41 * 42 * @global string $tinymce_version 43 * @global bool $concatenate_scripts 44 * @global bool $compress_scripts 45 * 46 * @param WP_Scripts $scripts WP_Scripts object. 47 * @param bool $force_uncompressed Whether to forcibly prevent gzip compression. Default false. 48 */ 49 function wp_register_tinymce_scripts( $scripts, $force_uncompressed = false ) { 50 global $tinymce_version, $concatenate_scripts, $compress_scripts; 51 52 $suffix = wp_scripts_get_suffix(); 53 $dev_suffix = wp_scripts_get_suffix( 'dev' ); 54 55 script_concat_settings(); 56 57 $compressed = $compress_scripts && $concatenate_scripts && isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) 58 && false !== stripos( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip' ) && ! $force_uncompressed; 59 60 // Load tinymce.js when running from /src, otherwise load wp-tinymce.js.gz (in production) 61 // or tinymce.min.js (when SCRIPT_DEBUG is true). 62 if ( $compressed ) { 63 $scripts->add( 'wp-tinymce', includes_url( 'js/tinymce/' ) . 'wp-tinymce.js', array(), $tinymce_version ); 64 } else { 65 $scripts->add( 'wp-tinymce-root', includes_url( 'js/tinymce/' ) . "tinymce$dev_suffix.js", array(), $tinymce_version ); 66 $scripts->add( 'wp-tinymce', includes_url( 'js/tinymce/' ) . "plugins/compat3x/plugin$dev_suffix.js", array( 'wp-tinymce-root' ), $tinymce_version ); 67 } 68 69 $scripts->add( 'wp-tinymce-lists', includes_url( "js/tinymce/plugins/lists/plugin$suffix.js" ), array( 'wp-tinymce' ), $tinymce_version ); 70 } 71 72 /** 73 * Registers all the WordPress vendor scripts that are in the standardized 74 * `js/dist/vendor/` location. 75 * 76 * For the order of `$scripts->add` see `wp_default_scripts`. 77 * 78 * @since 5.0.0 79 * 80 * @global WP_Locale $wp_locale WordPress date and time locale object. 81 * 82 * @param WP_Scripts $scripts WP_Scripts object. 83 */ 84 function wp_default_packages_vendor( $scripts ) { 85 global $wp_locale; 86 87 $suffix = wp_scripts_get_suffix(); 88 89 $vendor_scripts = array( 90 'react' => array( 'wp-polyfill' ), 91 'react-dom' => array( 'react' ), 92 'regenerator-runtime', 93 'moment', 94 'lodash', 95 'wp-polyfill-fetch', 96 'wp-polyfill-formdata', 97 'wp-polyfill-node-contains', 98 'wp-polyfill-url', 99 'wp-polyfill-dom-rect', 100 'wp-polyfill-element-closest', 101 'wp-polyfill-object-fit', 102 'wp-polyfill-inert', 103 'wp-polyfill' => array( 'wp-polyfill-inert', 'regenerator-runtime' ), 104 ); 105 106 $vendor_scripts_versions = array( 107 'react' => '18.2.0', 108 'react-dom' => '18.2.0', 109 'regenerator-runtime' => '0.13.11', 110 'moment' => '2.29.4', 111 'lodash' => '4.17.19', 112 'wp-polyfill-fetch' => '3.6.2', 113 'wp-polyfill-formdata' => '4.0.10', 114 'wp-polyfill-node-contains' => '4.6.0', 115 'wp-polyfill-url' => '3.6.4', 116 'wp-polyfill-dom-rect' => '4.6.0', 117 'wp-polyfill-element-closest' => '3.0.2', 118 'wp-polyfill-object-fit' => '2.3.5', 119 'wp-polyfill-inert' => '3.1.2', 120 'wp-polyfill' => '3.15.0', 121 ); 122 123 foreach ( $vendor_scripts as $handle => $dependencies ) { 124 if ( is_string( $dependencies ) ) { 125 $handle = $dependencies; 126 $dependencies = array(); 127 } 128 129 $path = "/wp-includes/js/dist/vendor/$handle$suffix.js"; 130 $version = $vendor_scripts_versions[ $handle ]; 131 132 $scripts->add( $handle, $path, $dependencies, $version, 1 ); 133 } 134 135 did_action( 'init' ) && $scripts->add_inline_script( 'lodash', 'window.lodash = _.noConflict();' ); 136 137 did_action( 'init' ) && $scripts->add_inline_script( 138 'moment', 139 sprintf( 140 "moment.updateLocale( '%s', %s );", 141 get_user_locale(), 142 wp_json_encode( 143 array( 144 'months' => array_values( $wp_locale->month ), 145 'monthsShort' => array_values( $wp_locale->month_abbrev ), 146 'weekdays' => array_values( $wp_locale->weekday ), 147 'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ), 148 'week' => array( 149 'dow' => (int) get_option( 'start_of_week', 0 ), 150 ), 151 'longDateFormat' => array( 152 'LT' => get_option( 'time_format', __( 'g:i a' ) ), 153 'LTS' => null, 154 'L' => null, 155 'LL' => get_option( 'date_format', __( 'F j, Y' ) ), 156 'LLL' => __( 'F j, Y g:i a' ), 157 'LLLL' => null, 158 ), 159 ) 160 ) 161 ), 162 'after' 163 ); 164 } 165 166 /** 167 * Returns contents of an inline script used in appending polyfill scripts for 168 * browsers which fail the provided tests. The provided array is a mapping from 169 * a condition to verify feature support to its polyfill script handle. 170 * 171 * @since 5.0.0 172 * 173 * @param WP_Scripts $scripts WP_Scripts object. 174 * @param string[] $tests Features to detect. 175 * @return string Conditional polyfill inline script. 176 */ 177 function wp_get_script_polyfill( $scripts, $tests ) { 178 $polyfill = ''; 179 foreach ( $tests as $test => $handle ) { 180 if ( ! array_key_exists( $handle, $scripts->registered ) ) { 181 continue; 182 } 183 184 $src = $scripts->registered[ $handle ]->src; 185 $ver = $scripts->registered[ $handle ]->ver; 186 187 if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $scripts->content_url && str_starts_with( $src, $scripts->content_url ) ) ) { 188 $src = $scripts->base_url . $src; 189 } 190 191 if ( ! empty( $ver ) ) { 192 $src = add_query_arg( 'ver', $ver, $src ); 193 } 194 195 /** This filter is documented in wp-includes/class-wp-scripts.php */ 196 $src = esc_url( apply_filters( 'script_loader_src', $src, $handle ) ); 197 198 if ( ! $src ) { 199 continue; 200 } 201 202 $polyfill .= ( 203 // Test presence of feature... 204 '( ' . $test . ' ) || ' . 205 /* 206 * ...appending polyfill on any failures. Cautious viewers may balk 207 * at the `document.write`. Its caveat of synchronous mid-stream 208 * blocking write is exactly the behavior we need though. 209 */ 210 'document.write( \'<script src="' . 211 $src . 212 '"></scr\' + \'ipt>\' );' 213 ); 214 } 215 216 return $polyfill; 217 } 218 219 /** 220 * Registers development scripts that integrate with `@wordpress/scripts`. 221 * 222 * @see https://github.com/WordPress/gutenberg/tree/trunk/packages/scripts#start 223 * 224 * @since 6.0.0 225 * 226 * @param WP_Scripts $scripts WP_Scripts object. 227 */ 228 function wp_register_development_scripts( $scripts ) { 229 if ( 230 ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG 231 || empty( $scripts->registered['react'] ) 232 || defined( 'WP_RUN_CORE_TESTS' ) 233 ) { 234 return; 235 } 236 237 $development_scripts = array( 238 'react-refresh-entry', 239 'react-refresh-runtime', 240 ); 241 242 foreach ( $development_scripts as $script_name ) { 243 $assets = include ABSPATH . WPINC . '/assets/script-loader-' . $script_name . '.php'; 244 if ( ! is_array( $assets ) ) { 245 return; 246 } 247 $scripts->add( 248 'wp-' . $script_name, 249 '/wp-includes/js/dist/development/' . $script_name . '.js', 250 $assets['dependencies'], 251 $assets['version'] 252 ); 253 } 254 255 // See https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/TROUBLESHOOTING.md#externalising-react. 256 $scripts->registered['react']->deps[] = 'wp-react-refresh-entry'; 257 } 258 259 /** 260 * Registers all the WordPress packages scripts that are in the standardized 261 * `js/dist/` location. 262 * 263 * For the order of `$scripts->add` see `wp_default_scripts`. 264 * 265 * @since 5.0.0 266 * 267 * @param WP_Scripts $scripts WP_Scripts object. 268 */ 269 function wp_default_packages_scripts( $scripts ) { 270 $suffix = defined( 'WP_RUN_CORE_TESTS' ) ? '.min' : wp_scripts_get_suffix(); 271 /* 272 * Expects multidimensional array like: 273 * 274 * 'a11y.js' => array('dependencies' => array(...), 'version' => '...'), 275 * 'annotations.js' => array('dependencies' => array(...), 'version' => '...'), 276 * 'api-fetch.js' => array(... 277 */ 278 $assets = include ABSPATH . WPINC . "/assets/script-loader-packages{$suffix}.php"; 279 280 foreach ( $assets as $file_name => $package_data ) { 281 $basename = str_replace( $suffix . '.js', '', basename( $file_name ) ); 282 $handle = 'wp-' . $basename; 283 $path = "/wp-includes/js/dist/{$basename}{$suffix}.js"; 284 285 if ( ! empty( $package_data['dependencies'] ) ) { 286 $dependencies = $package_data['dependencies']; 287 } else { 288 $dependencies = array(); 289 } 290 291 // Add dependencies that cannot be detected and generated by build tools. 292 switch ( $handle ) { 293 case 'wp-block-library': 294 array_push( $dependencies, 'editor' ); 295 break; 296 case 'wp-edit-post': 297 array_push( $dependencies, 'media-models', 'media-views', 'postbox', 'wp-dom-ready' ); 298 break; 299 case 'wp-preferences': 300 array_push( $dependencies, 'wp-preferences-persistence' ); 301 break; 302 } 303 304 $scripts->add( $handle, $path, $dependencies, $package_data['version'], 1 ); 305 306 if ( in_array( 'wp-i18n', $dependencies, true ) ) { 307 $scripts->set_translations( $handle ); 308 } 309 310 /* 311 * Manually set the text direction localization after wp-i18n is printed. 312 * This ensures that wp.i18n.isRTL() returns true in RTL languages. 313 * We cannot use $scripts->set_translations( 'wp-i18n' ) to do this 314 * because WordPress prints a script's translations *before* the script, 315 * which means, in the case of wp-i18n, that wp.i18n.setLocaleData() 316 * is called before wp.i18n is defined. 317 */ 318 if ( 'wp-i18n' === $handle ) { 319 $ltr = _x( 'ltr', 'text direction' ); 320 $script = sprintf( "wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ '%s' ] } );", $ltr ); 321 $scripts->add_inline_script( $handle, $script, 'after' ); 322 } 323 } 324 } 325 326 /** 327 * Adds inline scripts required for the WordPress JavaScript packages. 328 * 329 * @since 5.0.0 330 * 331 * @global WP_Locale $wp_locale WordPress date and time locale object. 332 * @global wpdb $wpdb WordPress database abstraction object. 333 * 334 * @param WP_Scripts $scripts WP_Scripts object. 335 */ 336 function wp_default_packages_inline_scripts( $scripts ) { 337 global $wp_locale, $wpdb; 338 339 if ( isset( $scripts->registered['wp-api-fetch'] ) ) { 340 $scripts->registered['wp-api-fetch']->deps[] = 'wp-hooks'; 341 } 342 $scripts->add_inline_script( 343 'wp-api-fetch', 344 sprintf( 345 'wp.apiFetch.use( wp.apiFetch.createRootURLMiddleware( "%s" ) );', 346 sanitize_url( get_rest_url() ) 347 ), 348 'after' 349 ); 350 $scripts->add_inline_script( 351 'wp-api-fetch', 352 implode( 353 "\n", 354 array( 355 sprintf( 356 'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );', 357 wp_installing() ? '' : wp_create_nonce( 'wp_rest' ) 358 ), 359 'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );', 360 'wp.apiFetch.use( wp.apiFetch.mediaUploadMiddleware );', 361 sprintf( 362 'wp.apiFetch.nonceEndpoint = "%s";', 363 admin_url( 'admin-ajax.php?action=rest-nonce' ) 364 ), 365 ) 366 ), 367 'after' 368 ); 369 370 $meta_key = $wpdb->get_blog_prefix() . 'persisted_preferences'; 371 $user_id = get_current_user_id(); 372 $preload_data = get_user_meta( $user_id, $meta_key, true ); 373 $scripts->add_inline_script( 374 'wp-preferences', 375 sprintf( 376 '( function() { 377 var serverData = %s; 378 var userId = "%d"; 379 var persistenceLayer = wp.preferencesPersistence.__unstableCreatePersistenceLayer( serverData, userId ); 380 var preferencesStore = wp.preferences.store; 381 wp.data.dispatch( preferencesStore ).setPersistenceLayer( persistenceLayer ); 382 } ) ();', 383 wp_json_encode( $preload_data ), 384 $user_id 385 ) 386 ); 387 388 // Backwards compatibility - configure the old wp-data persistence system. 389 $scripts->add_inline_script( 390 'wp-data', 391 implode( 392 "\n", 393 array( 394 '( function() {', 395 ' var userId = ' . get_current_user_ID() . ';', 396 ' var storageKey = "WP_DATA_USER_" + userId;', 397 ' wp.data', 398 ' .use( wp.data.plugins.persistence, { storageKey: storageKey } );', 399 '} )();', 400 ) 401 ) 402 ); 403 404 // Calculate the timezone abbr (EDT, PST) if possible. 405 $timezone_string = get_option( 'timezone_string', 'UTC' ); 406 $timezone_abbr = ''; 407 408 if ( ! empty( $timezone_string ) ) { 409 $timezone_date = new DateTime( 'now', new DateTimeZone( $timezone_string ) ); 410 $timezone_abbr = $timezone_date->format( 'T' ); 411 } 412 413 $scripts->add_inline_script( 414 'wp-date', 415 sprintf( 416 'wp.date.setSettings( %s );', 417 wp_json_encode( 418 array( 419 'l10n' => array( 420 'locale' => get_user_locale(), 421 'months' => array_values( $wp_locale->month ), 422 'monthsShort' => array_values( $wp_locale->month_abbrev ), 423 'weekdays' => array_values( $wp_locale->weekday ), 424 'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ), 425 'meridiem' => (object) $wp_locale->meridiem, 426 'relative' => array( 427 /* translators: %s: Duration. */ 428 'future' => __( '%s from now' ), 429 /* translators: %s: Duration. */ 430 'past' => __( '%s ago' ), 431 ), 432 'startOfWeek' => (int) get_option( 'start_of_week', 0 ), 433 ), 434 'formats' => array( 435 /* translators: Time format, see https://www.php.net/manual/datetime.format.php */ 436 'time' => get_option( 'time_format', __( 'g:i a' ) ), 437 /* translators: Date format, see https://www.php.net/manual/datetime.format.php */ 438 'date' => get_option( 'date_format', __( 'F j, Y' ) ), 439 /* translators: Date/Time format, see https://www.php.net/manual/datetime.format.php */ 440 'datetime' => __( 'F j, Y g:i a' ), 441 /* translators: Abbreviated date/time format, see https://www.php.net/manual/datetime.format.php */ 442 'datetimeAbbreviated' => __( 'M j, Y g:i a' ), 443 ), 444 'timezone' => array( 445 'offset' => (float) get_option( 'gmt_offset', 0 ), 446 'string' => $timezone_string, 447 'abbr' => $timezone_abbr, 448 ), 449 ) 450 ) 451 ), 452 'after' 453 ); 454 455 // Loading the old editor and its config to ensure the classic block works as expected. 456 $scripts->add_inline_script( 457 'editor', 458 'window.wp.oldEditor = window.wp.editor;', 459 'after' 460 ); 461 462 /* 463 * wp-editor module is exposed as window.wp.editor. 464 * Problem: there is quite some code expecting window.wp.oldEditor object available under window.wp.editor. 465 * Solution: fuse the two objects together to maintain backward compatibility. 466 * For more context, see https://github.com/WordPress/gutenberg/issues/33203. 467 */ 468 $scripts->add_inline_script( 469 'wp-editor', 470 'Object.assign( window.wp.editor, window.wp.oldEditor );', 471 'after' 472 ); 473 } 474 475 /** 476 * Adds inline scripts required for the TinyMCE in the block editor. 477 * 478 * These TinyMCE init settings are used to extend and override the default settings 479 * from `_WP_Editors::default_settings()` for the Classic block. 480 * 481 * @since 5.0.0 482 * 483 * @global WP_Scripts $wp_scripts 484 */ 485 function wp_tinymce_inline_scripts() { 486 global $wp_scripts; 487 488 /** This filter is documented in wp-includes/class-wp-editor.php */ 489 $editor_settings = apply_filters( 'wp_editor_settings', array( 'tinymce' => true ), 'classic-block' ); 490 491 $tinymce_plugins = array( 492 'charmap', 493 'colorpicker', 494 'hr', 495 'lists', 496 'media', 497 'paste', 498 'tabfocus', 499 'textcolor', 500 'fullscreen', 501 'wordpress', 502 'wpautoresize', 503 'wpeditimage', 504 'wpemoji', 505 'wpgallery', 506 'wplink', 507 'wpdialogs', 508 'wptextpattern', 509 'wpview', 510 ); 511 512 /** This filter is documented in wp-includes/class-wp-editor.php */ 513 $tinymce_plugins = apply_filters( 'tiny_mce_plugins', $tinymce_plugins, 'classic-block' ); 514 $tinymce_plugins = array_unique( $tinymce_plugins ); 515 516 $disable_captions = false; 517 // Runs after `tiny_mce_plugins` but before `mce_buttons`. 518 /** This filter is documented in wp-admin/includes/media.php */ 519 if ( apply_filters( 'disable_captions', '' ) ) { 520 $disable_captions = true; 521 } 522 523 $toolbar1 = array( 524 'formatselect', 525 'bold', 526 'italic', 527 'bullist', 528 'numlist', 529 'blockquote', 530 'alignleft', 531 'aligncenter', 532 'alignright', 533 'link', 534 'unlink', 535 'wp_more', 536 'spellchecker', 537 'wp_add_media', 538 'wp_adv', 539 ); 540 541 /** This filter is documented in wp-includes/class-wp-editor.php */ 542 $toolbar1 = apply_filters( 'mce_buttons', $toolbar1, 'classic-block' ); 543 544 $toolbar2 = array( 545 'strikethrough', 546 'hr', 547 'forecolor', 548 'pastetext', 549 'removeformat', 550 'charmap', 551 'outdent', 552 'indent', 553 'undo', 554 'redo', 555 'wp_help', 556 ); 557 558 /** This filter is documented in wp-includes/class-wp-editor.php */ 559 $toolbar2 = apply_filters( 'mce_buttons_2', $toolbar2, 'classic-block' ); 560 /** This filter is documented in wp-includes/class-wp-editor.php */ 561 $toolbar3 = apply_filters( 'mce_buttons_3', array(), 'classic-block' ); 562 /** This filter is documented in wp-includes/class-wp-editor.php */ 563 $toolbar4 = apply_filters( 'mce_buttons_4', array(), 'classic-block' ); 564 /** This filter is documented in wp-includes/class-wp-editor.php */ 565 $external_plugins = apply_filters( 'mce_external_plugins', array(), 'classic-block' ); 566 567 $tinymce_settings = array( 568 'plugins' => implode( ',', $tinymce_plugins ), 569 'toolbar1' => implode( ',', $toolbar1 ), 570 'toolbar2' => implode( ',', $toolbar2 ), 571 'toolbar3' => implode( ',', $toolbar3 ), 572 'toolbar4' => implode( ',', $toolbar4 ), 573 'external_plugins' => wp_json_encode( $external_plugins ), 574 'classic_block_editor' => true, 575 ); 576 577 if ( $disable_captions ) { 578 $tinymce_settings['wpeditimage_disable_captions'] = true; 579 } 580 581 if ( ! empty( $editor_settings['tinymce'] ) && is_array( $editor_settings['tinymce'] ) ) { 582 array_merge( $tinymce_settings, $editor_settings['tinymce'] ); 583 } 584 585 /** This filter is documented in wp-includes/class-wp-editor.php */ 586 $tinymce_settings = apply_filters( 'tiny_mce_before_init', $tinymce_settings, 'classic-block' ); 587 588 // Do "by hand" translation from PHP array to js object. 589 // Prevents breakage in some custom settings. 590 $init_obj = ''; 591 foreach ( $tinymce_settings as $key => $value ) { 592 if ( is_bool( $value ) ) { 593 $val = $value ? 'true' : 'false'; 594 $init_obj .= $key . ':' . $val . ','; 595 continue; 596 } elseif ( ! empty( $value ) && is_string( $value ) && ( 597 ( '{' === $value[0] && '}' === $value[ strlen( $value ) - 1 ] ) || 598 ( '[' === $value[0] && ']' === $value[ strlen( $value ) - 1 ] ) || 599 preg_match( '/^\(?function ?\(/', $value ) ) ) { 600 $init_obj .= $key . ':' . $value . ','; 601 continue; 602 } 603 $init_obj .= $key . ':"' . $value . '",'; 604 } 605 606 $init_obj = '{' . trim( $init_obj, ' ,' ) . '}'; 607 608 $script = 'window.wpEditorL10n = { 609 tinymce: { 610 baseURL: ' . wp_json_encode( includes_url( 'js/tinymce' ) ) . ', 611 suffix: ' . ( SCRIPT_DEBUG ? '""' : '".min"' ) . ', 612 settings: ' . $init_obj . ', 613 } 614 }'; 615 616 $wp_scripts->add_inline_script( 'wp-block-library', $script, 'before' ); 617 } 618 619 /** 620 * Registers all the WordPress packages scripts. 621 * 622 * @since 5.0.0 623 * 624 * @param WP_Scripts $scripts WP_Scripts object. 625 */ 626 function wp_default_packages( $scripts ) { 627 wp_default_packages_vendor( $scripts ); 628 wp_register_development_scripts( $scripts ); 629 wp_register_tinymce_scripts( $scripts ); 630 wp_default_packages_scripts( $scripts ); 631 632 if ( did_action( 'init' ) ) { 633 wp_default_packages_inline_scripts( $scripts ); 634 } 635 } 636 637 /** 638 * Returns the suffix that can be used for the scripts. 639 * 640 * There are two suffix types, the normal one and the dev suffix. 641 * 642 * @since 5.0.0 643 * 644 * @param string $type The type of suffix to retrieve. 645 * @return string The script suffix. 646 */ 647 function wp_scripts_get_suffix( $type = '' ) { 648 static $suffixes; 649 650 if ( null === $suffixes ) { 651 // Include an unmodified $wp_version. 652 require ABSPATH . WPINC . '/version.php'; 653 654 $develop_src = false !== strpos( $wp_version, '-src' ); 655 656 if ( ! defined( 'SCRIPT_DEBUG' ) ) { 657 define( 'SCRIPT_DEBUG', $develop_src ); 658 } 659 $suffix = SCRIPT_DEBUG ? '' : '.min'; 660 $dev_suffix = $develop_src ? '' : '.min'; 661 662 $suffixes = array( 663 'suffix' => $suffix, 664 'dev_suffix' => $dev_suffix, 665 ); 666 } 667 668 if ( 'dev' === $type ) { 669 return $suffixes['dev_suffix']; 670 } 671 672 return $suffixes['suffix']; 673 } 674 675 /** 676 * Registers all WordPress scripts. 677 * 678 * Localizes some of them. 679 * args order: `$scripts->add( 'handle', 'url', 'dependencies', 'query-string', 1 );` 680 * when last arg === 1 queues the script for the footer 681 * 682 * @since 2.6.0 683 * 684 * @param WP_Scripts $scripts WP_Scripts object. 685 */ 686 function wp_default_scripts( $scripts ) { 687 $suffix = wp_scripts_get_suffix(); 688 $dev_suffix = wp_scripts_get_suffix( 'dev' ); 689 $guessurl = site_url(); 690 691 if ( ! $guessurl ) { 692 $guessed_url = true; 693 $guessurl = wp_guess_url(); 694 } 695 696 $scripts->base_url = $guessurl; 697 $scripts->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : ''; 698 $scripts->default_version = get_bloginfo( 'version' ); 699 $scripts->default_dirs = array( '/wp-admin/js/', '/wp-includes/js/' ); 700 701 $scripts->add( 'utils', "/wp-includes/js/utils$suffix.js" ); 702 did_action( 'init' ) && $scripts->localize( 703 'utils', 704 'userSettings', 705 array( 706 'url' => (string) SITECOOKIEPATH, 707 'uid' => (string) get_current_user_id(), 708 'time' => (string) time(), 709 'secure' => (string) ( 'https' === parse_url( site_url(), PHP_URL_SCHEME ) ), 710 ) 711 ); 712 713 $scripts->add( 'common', "/wp-admin/js/common$suffix.js", array( 'jquery', 'hoverIntent', 'utils' ), false, 1 ); 714 $scripts->set_translations( 'common' ); 715 716 $scripts->add( 'wp-sanitize', "/wp-includes/js/wp-sanitize$suffix.js", array(), false, 1 ); 717 718 $scripts->add( 'sack', "/wp-includes/js/tw-sack$suffix.js", array(), '1.6.1', 1 ); 719 720 $scripts->add( 'quicktags', "/wp-includes/js/quicktags$suffix.js", array(), false, 1 ); 721 did_action( 'init' ) && $scripts->localize( 722 'quicktags', 723 'quicktagsL10n', 724 array( 725 'closeAllOpenTags' => __( 'Close all open tags' ), 726 'closeTags' => __( 'close tags' ), 727 'enterURL' => __( 'Enter the URL' ), 728 'enterImageURL' => __( 'Enter the URL of the image' ), 729 'enterImageDescription' => __( 'Enter a description of the image' ), 730 'textdirection' => __( 'text direction' ), 731 'toggleTextdirection' => __( 'Toggle Editor Text Direction' ), 732 'dfw' => __( 'Distraction-free writing mode' ), 733 'strong' => __( 'Bold' ), 734 'strongClose' => __( 'Close bold tag' ), 735 'em' => __( 'Italic' ), 736 'emClose' => __( 'Close italic tag' ), 737 'link' => __( 'Insert link' ), 738 'blockquote' => __( 'Blockquote' ), 739 'blockquoteClose' => __( 'Close blockquote tag' ), 740 'del' => __( 'Deleted text (strikethrough)' ), 741 'delClose' => __( 'Close deleted text tag' ), 742 'ins' => __( 'Inserted text' ), 743 'insClose' => __( 'Close inserted text tag' ), 744 'image' => __( 'Insert image' ), 745 'ul' => __( 'Bulleted list' ), 746 'ulClose' => __( 'Close bulleted list tag' ), 747 'ol' => __( 'Numbered list' ), 748 'olClose' => __( 'Close numbered list tag' ), 749 'li' => __( 'List item' ), 750 'liClose' => __( 'Close list item tag' ), 751 'code' => __( 'Code' ), 752 'codeClose' => __( 'Close code tag' ), 753 'more' => __( 'Insert Read More tag' ), 754 ) 755 ); 756 757 $scripts->add( 'colorpicker', "/wp-includes/js/colorpicker$suffix.js", array( 'prototype' ), '3517m' ); 758 759 $scripts->add( 'editor', "/wp-admin/js/editor$suffix.js", array( 'utils', 'jquery' ), false, 1 ); 760 761 $scripts->add( 'clipboard', "/wp-includes/js/clipboard$suffix.js", array(), '2.0.11', 1 ); 762 763 $scripts->add( 'wp-ajax-response', "/wp-includes/js/wp-ajax-response$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 ); 764 did_action( 'init' ) && $scripts->localize( 765 'wp-ajax-response', 766 'wpAjax', 767 array( 768 'noPerm' => __( 'Sorry, you are not allowed to do that.' ), 769 'broken' => __( 'Something went wrong.' ), 770 ) 771 ); 772 773 $scripts->add( 'wp-api-request', "/wp-includes/js/api-request$suffix.js", array( 'jquery' ), false, 1 ); 774 // `wpApiSettings` is also used by `wp-api`, which depends on this script. 775 did_action( 'init' ) && $scripts->localize( 776 'wp-api-request', 777 'wpApiSettings', 778 array( 779 'root' => sanitize_url( get_rest_url() ), 780 'nonce' => wp_installing() ? '' : wp_create_nonce( 'wp_rest' ), 781 'versionString' => 'wp/v2/', 782 ) 783 ); 784 785 $scripts->add( 'wp-pointer', "/wp-includes/js/wp-pointer$suffix.js", array( 'jquery-ui-core' ), false, 1 ); 786 $scripts->set_translations( 'wp-pointer' ); 787 788 $scripts->add( 'autosave', "/wp-includes/js/autosave$suffix.js", array( 'heartbeat' ), false, 1 ); 789 790 $scripts->add( 'heartbeat', "/wp-includes/js/heartbeat$suffix.js", array( 'jquery', 'wp-hooks' ), false, 1 ); 791 did_action( 'init' ) && $scripts->localize( 792 'heartbeat', 793 'heartbeatSettings', 794 /** 795 * Filters the Heartbeat settings. 796 * 797 * @since 3.6.0 798 * 799 * @param array $settings Heartbeat settings array. 800 */ 801 apply_filters( 'heartbeat_settings', array() ) 802 ); 803 804 $scripts->add( 'wp-auth-check', "/wp-includes/js/wp-auth-check$suffix.js", array( 'heartbeat' ), false, 1 ); 805 $scripts->set_translations( 'wp-auth-check' ); 806 807 $scripts->add( 'wp-lists', "/wp-includes/js/wp-lists$suffix.js", array( 'wp-ajax-response', 'jquery-color' ), false, 1 ); 808 809 // WordPress no longer uses or bundles Prototype or script.aculo.us. These are now pulled from an external source. 810 $scripts->add( 'prototype', 'https://ajax.googleapis.com/ajax/libs/prototype/1.7.1.0/prototype.js', array(), '1.7.1' ); 811 $scripts->add( 'scriptaculous-root', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/scriptaculous.js', array( 'prototype' ), '1.9.0' ); 812 $scripts->add( 'scriptaculous-builder', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/builder.js', array( 'scriptaculous-root' ), '1.9.0' ); 813 $scripts->add( 'scriptaculous-dragdrop', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/dragdrop.js', array( 'scriptaculous-builder', 'scriptaculous-effects' ), '1.9.0' ); 814 $scripts->add( 'scriptaculous-effects', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/effects.js', array( 'scriptaculous-root' ), '1.9.0' ); 815 $scripts->add( 'scriptaculous-slider', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/slider.js', array( 'scriptaculous-effects' ), '1.9.0' ); 816 $scripts->add( 'scriptaculous-sound', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/sound.js', array( 'scriptaculous-root' ), '1.9.0' ); 817 $scripts->add( 'scriptaculous-controls', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/controls.js', array( 'scriptaculous-root' ), '1.9.0' ); 818 $scripts->add( 'scriptaculous', false, array( 'scriptaculous-dragdrop', 'scriptaculous-slider', 'scriptaculous-controls' ) ); 819 820 // Not used in core, replaced by Jcrop.js. 821 $scripts->add( 'cropper', '/wp-includes/js/crop/cropper.js', array( 'scriptaculous-dragdrop' ) ); 822 823 // jQuery. 824 // The unminified jquery.js and jquery-migrate.js are included to facilitate debugging. 825 $scripts->add( 'jquery', false, array( 'jquery-core', 'jquery-migrate' ), '3.7.0' ); 826 $scripts->add( 'jquery-core', "/wp-includes/js/jquery/jquery$suffix.js", array(), '3.7.0' ); 827 $scripts->add( 'jquery-migrate', "/wp-includes/js/jquery/jquery-migrate$suffix.js", array(), '3.4.0' ); 828 829 // Full jQuery UI. 830 // The build process in 1.12.1 has changed significantly. 831 // In order to keep backwards compatibility, and to keep the optimized loading, 832 // the source files were flattened and included with some modifications for AMD loading. 833 // A notable change is that 'jquery-ui-core' now contains 'jquery-ui-position' and 'jquery-ui-widget'. 834 $scripts->add( 'jquery-ui-core', "/wp-includes/js/jquery/ui/core$suffix.js", array( 'jquery' ), '1.13.2', 1 ); 835 $scripts->add( 'jquery-effects-core', "/wp-includes/js/jquery/ui/effect$suffix.js", array( 'jquery' ), '1.13.2', 1 ); 836 837 $scripts->add( 'jquery-effects-blind', "/wp-includes/js/jquery/ui/effect-blind$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 838 $scripts->add( 'jquery-effects-bounce', "/wp-includes/js/jquery/ui/effect-bounce$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 839 $scripts->add( 'jquery-effects-clip', "/wp-includes/js/jquery/ui/effect-clip$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 840 $scripts->add( 'jquery-effects-drop', "/wp-includes/js/jquery/ui/effect-drop$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 841 $scripts->add( 'jquery-effects-explode', "/wp-includes/js/jquery/ui/effect-explode$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 842 $scripts->add( 'jquery-effects-fade', "/wp-includes/js/jquery/ui/effect-fade$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 843 $scripts->add( 'jquery-effects-fold', "/wp-includes/js/jquery/ui/effect-fold$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 844 $scripts->add( 'jquery-effects-highlight', "/wp-includes/js/jquery/ui/effect-highlight$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 845 $scripts->add( 'jquery-effects-puff', "/wp-includes/js/jquery/ui/effect-puff$suffix.js", array( 'jquery-effects-core', 'jquery-effects-scale' ), '1.13.2', 1 ); 846 $scripts->add( 'jquery-effects-pulsate', "/wp-includes/js/jquery/ui/effect-pulsate$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 847 $scripts->add( 'jquery-effects-scale', "/wp-includes/js/jquery/ui/effect-scale$suffix.js", array( 'jquery-effects-core', 'jquery-effects-size' ), '1.13.2', 1 ); 848 $scripts->add( 'jquery-effects-shake', "/wp-includes/js/jquery/ui/effect-shake$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 849 $scripts->add( 'jquery-effects-size', "/wp-includes/js/jquery/ui/effect-size$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 850 $scripts->add( 'jquery-effects-slide', "/wp-includes/js/jquery/ui/effect-slide$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 851 $scripts->add( 'jquery-effects-transfer', "/wp-includes/js/jquery/ui/effect-transfer$suffix.js", array( 'jquery-effects-core' ), '1.13.2', 1 ); 852 853 // Widgets 854 $scripts->add( 'jquery-ui-accordion', "/wp-includes/js/jquery/ui/accordion$suffix.js", array( 'jquery-ui-core' ), '1.13.2', 1 ); 855 $scripts->add( 'jquery-ui-autocomplete', "/wp-includes/js/jquery/ui/autocomplete$suffix.js", array( 'jquery-ui-menu', 'wp-a11y' ), '1.13.2', 1 ); 856 $scripts->add( 'jquery-ui-button', "/wp-includes/js/jquery/ui/button$suffix.js", array( 'jquery-ui-core', 'jquery-ui-controlgroup', 'jquery-ui-checkboxradio' ), '1.13.2', 1 ); 857 $scripts->add( 'jquery-ui-datepicker', "/wp-includes/js/jquery/ui/datepicker$suffix.js", array( 'jquery-ui-core' ), '1.13.2', 1 ); 858 $scripts->add( 'jquery-ui-dialog', "/wp-includes/js/jquery/ui/dialog$suffix.js", array( 'jquery-ui-resizable', 'jquery-ui-draggable', 'jquery-ui-button' ), '1.13.2', 1 ); 859 $scripts->add( 'jquery-ui-menu', "/wp-includes/js/jquery/ui/menu$suffix.js", array( 'jquery-ui-core' ), '1.13.2', 1 ); 860 $scripts->add( 'jquery-ui-mouse', "/wp-includes/js/jquery/ui/mouse$suffix.js", array( 'jquery-ui-core' ), '1.13.2', 1 ); 861 $scripts->add( 'jquery-ui-progressbar', "/wp-includes/js/jquery/ui/progressbar$suffix.js", array( 'jquery-ui-core' ), '1.13.2', 1 ); 862 $scripts->add( 'jquery-ui-selectmenu', "/wp-includes/js/jquery/ui/selectmenu$suffix.js", array( 'jquery-ui-menu' ), '1.13.2', 1 ); 863 $scripts->add( 'jquery-ui-slider', "/wp-includes/js/jquery/ui/slider$suffix.js", array( 'jquery-ui-mouse' ), '1.13.2', 1 ); 864 $scripts->add( 'jquery-ui-spinner', "/wp-includes/js/jquery/ui/spinner$suffix.js", array( 'jquery-ui-button' ), '1.13.2', 1 ); 865 $scripts->add( 'jquery-ui-tabs', "/wp-includes/js/jquery/ui/tabs$suffix.js", array( 'jquery-ui-core' ), '1.13.2', 1 ); 866 $scripts->add( 'jquery-ui-tooltip', "/wp-includes/js/jquery/ui/tooltip$suffix.js", array( 'jquery-ui-core' ), '1.13.2', 1 ); 867 868 // New in 1.12.1 869 $scripts->add( 'jquery-ui-checkboxradio', "/wp-includes/js/jquery/ui/checkboxradio$suffix.js", array( 'jquery-ui-core' ), '1.13.2', 1 ); 870 $scripts->add( 'jquery-ui-controlgroup', "/wp-includes/js/jquery/ui/controlgroup$suffix.js", array( 'jquery-ui-core' ), '1.13.2', 1 ); 871 872 // Interactions 873 $scripts->add( 'jquery-ui-draggable', "/wp-includes/js/jquery/ui/draggable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.2', 1 ); 874 $scripts->add( 'jquery-ui-droppable', "/wp-includes/js/jquery/ui/droppable$suffix.js", array( 'jquery-ui-draggable' ), '1.13.2', 1 ); 875 $scripts->add( 'jquery-ui-resizable', "/wp-includes/js/jquery/ui/resizable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.2', 1 ); 876 $scripts->add( 'jquery-ui-selectable', "/wp-includes/js/jquery/ui/selectable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.2', 1 ); 877 $scripts->add( 'jquery-ui-sortable', "/wp-includes/js/jquery/ui/sortable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.2', 1 ); 878 879 // As of 1.12.1 `jquery-ui-position` and `jquery-ui-widget` are part of `jquery-ui-core`. 880 // Listed here for back-compat. 881 $scripts->add( 'jquery-ui-position', false, array( 'jquery-ui-core' ), '1.13.2', 1 ); 882 $scripts->add( 'jquery-ui-widget', false, array( 'jquery-ui-core' ), '1.13.2', 1 ); 883 884 // Strings for 'jquery-ui-autocomplete' live region messages. 885 did_action( 'init' ) && $scripts->localize( 886 'jquery-ui-autocomplete', 887 'uiAutocompleteL10n', 888 array( 889 'noResults' => __( 'No results found.' ), 890 /* translators: Number of results found when using jQuery UI Autocomplete. */ 891 'oneResult' => __( '1 result found. Use up and down arrow keys to navigate.' ), 892 /* translators: %d: Number of results found when using jQuery UI Autocomplete. */ 893 'manyResults' => __( '%d results found. Use up and down arrow keys to navigate.' ), 894 'itemSelected' => __( 'Item selected.' ), 895 ) 896 ); 897 898 // Deprecated, not used in core, most functionality is included in jQuery 1.3. 899 $scripts->add( 'jquery-form', "/wp-includes/js/jquery/jquery.form$suffix.js", array( 'jquery' ), '4.3.0', 1 ); 900 901 // jQuery plugins. 902 $scripts->add( 'jquery-color', '/wp-includes/js/jquery/jquery.color.min.js', array( 'jquery' ), '2.2.0', 1 ); 903 $scripts->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array( 'jquery' ), '20m', 1 ); 904 $scripts->add( 'jquery-query', '/wp-includes/js/jquery/jquery.query.js', array( 'jquery' ), '2.2.3', 1 ); 905 $scripts->add( 'jquery-serialize-object', '/wp-includes/js/jquery/jquery.serialize-object.js', array( 'jquery' ), '0.2-wp', 1 ); 906 $scripts->add( 'jquery-hotkeys', "/wp-includes/js/jquery/jquery.hotkeys$suffix.js", array( 'jquery' ), '0.0.2m', 1 ); 907 $scripts->add( 'jquery-table-hotkeys', "/wp-includes/js/jquery/jquery.table-hotkeys$suffix.js", array( 'jquery', 'jquery-hotkeys' ), false, 1 ); 908 $scripts->add( 'jquery-touch-punch', '/wp-includes/js/jquery/jquery.ui.touch-punch.js', array( 'jquery-ui-core', 'jquery-ui-mouse' ), '0.2.2', 1 ); 909 910 // Not used any more, registered for backward compatibility. 911 $scripts->add( 'suggest', "/wp-includes/js/jquery/suggest$suffix.js", array( 'jquery' ), '1.1-20110113', 1 ); 912 913 // Masonry v2 depended on jQuery. v3 does not. The older jquery-masonry handle is a shiv. 914 // It sets jQuery as a dependency, as the theme may have been implicitly loading it this way. 915 $scripts->add( 'imagesloaded', '/wp-includes/js/imagesloaded.min.js', array(), '4.1.4', 1 ); 916 $scripts->add( 'masonry', '/wp-includes/js/masonry.min.js', array( 'imagesloaded' ), '4.2.2', 1 ); 917 $scripts->add( 'jquery-masonry', '/wp-includes/js/jquery/jquery.masonry.min.js', array( 'jquery', 'masonry' ), '3.1.2b', 1 ); 918 919 $scripts->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.js', array( 'jquery' ), '3.1-20121105', 1 ); 920 did_action( 'init' ) && $scripts->localize( 921 'thickbox', 922 'thickboxL10n', 923 array( 924 'next' => __( 'Next >' ), 925 'prev' => __( '< Prev' ), 926 'image' => __( 'Image' ), 927 'of' => __( 'of' ), 928 'close' => __( 'Close' ), 929 'noiframes' => __( 'This feature requires inline frames. You have iframes disabled or your browser does not support them.' ), 930 'loadingAnimation' => includes_url( 'js/thickbox/loadingAnimation.gif' ), 931 ) 932 ); 933 934 // Not used in core, replaced by imgAreaSelect. 935 $scripts->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.min.js', array( 'jquery' ), '0.9.15' ); 936 937 $scripts->add( 'swfobject', '/wp-includes/js/swfobject.js', array(), '2.2-20120417' ); 938 939 // Error messages for Plupload. 940 $uploader_l10n = array( 941 'queue_limit_exceeded' => __( 'You have attempted to queue too many files.' ), 942 /* translators: %s: File name. */ 943 'file_exceeds_size_limit' => __( '%s exceeds the maximum upload size for this site.' ), 944 'zero_byte_file' => __( 'This file is empty. Please try another.' ), 945 'invalid_filetype' => __( 'Sorry, you are not allowed to upload this file type.' ), 946 'not_an_image' => __( 'This file is not an image. Please try another.' ), 947 'image_memory_exceeded' => __( 'Memory exceeded. Please try another smaller file.' ), 948 'image_dimensions_exceeded' => __( 'This is larger than the maximum size. Please try another.' ), 949 'default_error' => __( 'An error occurred in the upload. Please try again later.' ), 950 'missing_upload_url' => __( 'There was a configuration error. Please contact the server administrator.' ), 951 'upload_limit_exceeded' => __( 'You may only upload 1 file.' ), 952 'http_error' => __( 'Unexpected response from the server. The file may have been uploaded successfully. Check in the Media Library or reload the page.' ), 953 'http_error_image' => __( 'The server cannot process the image. This can happen if the server is busy or does not have enough resources to complete the task. Uploading a smaller image may help. Suggested maximum size is 2560 pixels.' ), 954 'upload_failed' => __( 'Upload failed.' ), 955 /* translators: 1: Opening link tag, 2: Closing link tag. */ 956 'big_upload_failed' => __( 'Please try uploading this file with the %1$sbrowser uploader%2$s.' ), 957 /* translators: %s: File name. */ 958 'big_upload_queued' => __( '%s exceeds the maximum upload size for the multi-file uploader when used in your browser.' ), 959 'io_error' => __( 'IO error.' ), 960 'security_error' => __( 'Security error.' ), 961 'file_cancelled' => __( 'File canceled.' ), 962 'upload_stopped' => __( 'Upload stopped.' ), 963 'dismiss' => __( 'Dismiss' ), 964 'crunching' => __( 'Crunching…' ), 965 'deleted' => __( 'moved to the Trash.' ), 966 /* translators: %s: File name. */ 967 'error_uploading' => __( '“%s” has failed to upload.' ), 968 'unsupported_image' => __( 'This image cannot be displayed in a web browser. For best results convert it to JPEG before uploading.' ), 969 'noneditable_image' => __( 'This image cannot be processed by the web server. Convert it to JPEG or PNG before uploading.' ), 970 'file_url_copied' => __( 'The file URL has been copied to your clipboard' ), 971 ); 972 973 $scripts->add( 'moxiejs', "/wp-includes/js/plupload/moxie$suffix.js", array(), '1.3.5' ); 974 $scripts->add( 'plupload', "/wp-includes/js/plupload/plupload$suffix.js", array( 'moxiejs' ), '2.1.9' ); 975 // Back compat handles: 976 foreach ( array( 'all', 'html5', 'flash', 'silverlight', 'html4' ) as $handle ) { 977 $scripts->add( "plupload-$handle", false, array( 'plupload' ), '2.1.1' ); 978 } 979 980 $scripts->add( 'plupload-handlers', "/wp-includes/js/plupload/handlers$suffix.js", array( 'clipboard', 'jquery', 'plupload', 'underscore', 'wp-a11y', 'wp-i18n' ) ); 981 did_action( 'init' ) && $scripts->localize( 'plupload-handlers', 'pluploadL10n', $uploader_l10n ); 982 983 $scripts->add( 'wp-plupload', "/wp-includes/js/plupload/wp-plupload$suffix.js", array( 'plupload', 'jquery', 'json2', 'media-models' ), false, 1 ); 984 did_action( 'init' ) && $scripts->localize( 'wp-plupload', 'pluploadL10n', $uploader_l10n ); 985 986 // Keep 'swfupload' for back-compat. 987 $scripts->add( 'swfupload', '/wp-includes/js/swfupload/swfupload.js', array(), '2201-20110113' ); 988 $scripts->add( 'swfupload-all', false, array( 'swfupload' ), '2201' ); 989 $scripts->add( 'swfupload-handlers', "/wp-includes/js/swfupload/handlers$suffix.js", array( 'swfupload-all', 'jquery' ), '2201-20110524' ); 990 did_action( 'init' ) && $scripts->localize( 'swfupload-handlers', 'swfuploadL10n', $uploader_l10n ); 991 992 $scripts->add( 'comment-reply', "/wp-includes/js/comment-reply$suffix.js", array(), false, 1 ); 993 994 $scripts->add( 'json2', "/wp-includes/js/json2$suffix.js", array(), '2015-05-03' ); 995 did_action( 'init' ) && $scripts->add_data( 'json2', 'conditional', 'lt IE 8' ); 996 997 $scripts->add( 'underscore', "/wp-includes/js/underscore$dev_suffix.js", array(), '1.13.4', 1 ); 998 $scripts->add( 'backbone', "/wp-includes/js/backbone$dev_suffix.js", array( 'underscore', 'jquery' ), '1.4.1', 1 ); 999 1000 $scripts->add( 'wp-util', "/wp-includes/js/wp-util$suffix.js", array( 'underscore', 'jquery' ), false, 1 ); 1001 did_action( 'init' ) && $scripts->localize( 1002 'wp-util', 1003 '_wpUtilSettings', 1004 array( 1005 'ajax' => array( 1006 'url' => admin_url( 'admin-ajax.php', 'relative' ), 1007 ), 1008 ) 1009 ); 1010 1011 $scripts->add( 'wp-backbone', "/wp-includes/js/wp-backbone$suffix.js", array( 'backbone', 'wp-util' ), false, 1 ); 1012 1013 $scripts->add( 'revisions', "/wp-admin/js/revisions$suffix.js", array( 'wp-backbone', 'jquery-ui-slider', 'hoverIntent' ), false, 1 ); 1014 1015 $scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array( 'jquery' ), false, 1 ); 1016 1017 $scripts->add( 'mediaelement', false, array( 'jquery', 'mediaelement-core', 'mediaelement-migrate' ), '4.2.17', 1 ); 1018 $scripts->add( 'mediaelement-core', "/wp-includes/js/mediaelement/mediaelement-and-player$suffix.js", array(), '4.2.17', 1 ); 1019 $scripts->add( 'mediaelement-migrate', "/wp-includes/js/mediaelement/mediaelement-migrate$suffix.js", array(), false, 1 ); 1020 1021 did_action( 'init' ) && $scripts->add_inline_script( 1022 'mediaelement-core', 1023 sprintf( 1024 'var mejsL10n = %s;', 1025 wp_json_encode( 1026 array( 1027 'language' => strtolower( strtok( determine_locale(), '_-' ) ), 1028 'strings' => array( 1029 'mejs.download-file' => __( 'Download File' ), 1030 'mejs.install-flash' => __( 'You are using a browser that does not have Flash player enabled or installed. Please turn on your Flash player plugin or download the latest version from https://get.adobe.com/flashplayer/' ), 1031 'mejs.fullscreen' => __( 'Fullscreen' ), 1032 'mejs.play' => __( 'Play' ), 1033 'mejs.pause' => __( 'Pause' ), 1034 'mejs.time-slider' => __( 'Time Slider' ), 1035 'mejs.time-help-text' => __( 'Use Left/Right Arrow keys to advance one second, Up/Down arrows to advance ten seconds.' ), 1036 'mejs.live-broadcast' => __( 'Live Broadcast' ), 1037 'mejs.volume-help-text' => __( 'Use Up/Down Arrow keys to increase or decrease volume.' ), 1038 'mejs.unmute' => __( 'Unmute' ), 1039 'mejs.mute' => __( 'Mute' ), 1040 'mejs.volume-slider' => __( 'Volume Slider' ), 1041 'mejs.video-player' => __( 'Video Player' ), 1042 'mejs.audio-player' => __( 'Audio Player' ), 1043 'mejs.captions-subtitles' => __( 'Captions/Subtitles' ), 1044 'mejs.captions-chapters' => __( 'Chapters' ), 1045 'mejs.none' => __( 'None' ), 1046 'mejs.afrikaans' => __( 'Afrikaans' ), 1047 'mejs.albanian' => __( 'Albanian' ), 1048 'mejs.arabic' => __( 'Arabic' ), 1049 'mejs.belarusian' => __( 'Belarusian' ), 1050 'mejs.bulgarian' => __( 'Bulgarian' ), 1051 'mejs.catalan' => __( 'Catalan' ), 1052 'mejs.chinese' => __( 'Chinese' ), 1053 'mejs.chinese-simplified' => __( 'Chinese (Simplified)' ), 1054 'mejs.chinese-traditional' => __( 'Chinese (Traditional)' ), 1055 'mejs.croatian' => __( 'Croatian' ), 1056 'mejs.czech' => __( 'Czech' ), 1057 'mejs.danish' => __( 'Danish' ), 1058 'mejs.dutch' => __( 'Dutch' ), 1059 'mejs.english' => __( 'English' ), 1060 'mejs.estonian' => __( 'Estonian' ), 1061 'mejs.filipino' => __( 'Filipino' ), 1062 'mejs.finnish' => __( 'Finnish' ), 1063 'mejs.french' => __( 'French' ), 1064 'mejs.galician' => __( 'Galician' ), 1065 'mejs.german' => __( 'German' ), 1066 'mejs.greek' => __( 'Greek' ), 1067 'mejs.haitian-creole' => __( 'Haitian Creole' ), 1068 'mejs.hebrew' => __( 'Hebrew' ), 1069 'mejs.hindi' => __( 'Hindi' ), 1070 'mejs.hungarian' => __( 'Hungarian' ), 1071 'mejs.icelandic' => __( 'Icelandic' ), 1072 'mejs.indonesian' => __( 'Indonesian' ), 1073 'mejs.irish' => __( 'Irish' ), 1074 'mejs.italian' => __( 'Italian' ), 1075 'mejs.japanese' => __( 'Japanese' ), 1076 'mejs.korean' => __( 'Korean' ), 1077 'mejs.latvian' => __( 'Latvian' ), 1078 'mejs.lithuanian' => __( 'Lithuanian' ), 1079 'mejs.macedonian' => __( 'Macedonian' ), 1080 'mejs.malay' => __( 'Malay' ), 1081 'mejs.maltese' => __( 'Maltese' ), 1082 'mejs.norwegian' => __( 'Norwegian' ), 1083 'mejs.persian' => __( 'Persian' ), 1084 'mejs.polish' => __( 'Polish' ), 1085 'mejs.portuguese' => __( 'Portuguese' ), 1086 'mejs.romanian' => __( 'Romanian' ), 1087 'mejs.russian' => __( 'Russian' ), 1088 'mejs.serbian' => __( 'Serbian' ), 1089 'mejs.slovak' => __( 'Slovak' ), 1090 'mejs.slovenian' => __( 'Slovenian' ), 1091 'mejs.spanish' => __( 'Spanish' ), 1092 'mejs.swahili' => __( 'Swahili' ), 1093 'mejs.swedish' => __( 'Swedish' ), 1094 'mejs.tagalog' => __( 'Tagalog' ), 1095 'mejs.thai' => __( 'Thai' ), 1096 'mejs.turkish' => __( 'Turkish' ), 1097 'mejs.ukrainian' => __( 'Ukrainian' ), 1098 'mejs.vietnamese' => __( 'Vietnamese' ), 1099 'mejs.welsh' => __( 'Welsh' ), 1100 'mejs.yiddish' => __( 'Yiddish' ), 1101 ), 1102 ) 1103 ) 1104 ), 1105 'before' 1106 ); 1107 1108 $scripts->add( 'mediaelement-vimeo', '/wp-includes/js/mediaelement/renderers/vimeo.min.js', array( 'mediaelement' ), '4.2.17', 1 ); 1109 $scripts->add( 'wp-mediaelement', "/wp-includes/js/mediaelement/wp-mediaelement$suffix.js", array( 'mediaelement' ), false, 1 ); 1110 $mejs_settings = array( 1111 'pluginPath' => includes_url( 'js/mediaelement/', 'relative' ), 1112 'classPrefix' => 'mejs-', 1113 'stretching' => 'responsive', 1114 /** This filter is documented in wp-includes/media.php */ 1115 'audioShortcodeLibrary' => apply_filters( 'wp_audio_shortcode_library', 'mediaelement' ), 1116 /** This filter is documented in wp-includes/media.php */ 1117 'videoShortcodeLibrary' => apply_filters( 'wp_video_shortcode_library', 'mediaelement' ), 1118 ); 1119 did_action( 'init' ) && $scripts->localize( 1120 'mediaelement', 1121 '_wpmejsSettings', 1122 /** 1123 * Filters the MediaElement configuration settings. 1124 * 1125 * @since 4.4.0 1126 * 1127 * @param array $mejs_settings MediaElement settings array. 1128 */ 1129 apply_filters( 'mejs_settings', $mejs_settings ) 1130 ); 1131 1132 $scripts->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.js', array(), '5.29.1-alpha-ee20357' ); 1133 $scripts->add( 'csslint', '/wp-includes/js/codemirror/csslint.js', array(), '1.0.5' ); 1134 $scripts->add( 'esprima', '/wp-includes/js/codemirror/esprima.js', array(), '4.0.0' ); 1135 $scripts->add( 'jshint', '/wp-includes/js/codemirror/fakejshint.js', array( 'esprima' ), '2.9.5' ); 1136 $scripts->add( 'jsonlint', '/wp-includes/js/codemirror/jsonlint.js', array(), '1.6.2' ); 1137 $scripts->add( 'htmlhint', '/wp-includes/js/codemirror/htmlhint.js', array(), '0.9.14-xwp' ); 1138 $scripts->add( 'htmlhint-kses', '/wp-includes/js/codemirror/htmlhint-kses.js', array( 'htmlhint' ) ); 1139 $scripts->add( 'code-editor', "/wp-admin/js/code-editor$suffix.js", array( 'jquery', 'wp-codemirror', 'underscore' ) ); 1140 $scripts->add( 'wp-theme-plugin-editor', "/wp-admin/js/theme-plugin-editor$suffix.js", array( 'common', 'wp-util', 'wp-sanitize', 'jquery', 'jquery-ui-core', 'wp-a11y', 'underscore' ), false, 1 ); 1141 $scripts->set_translations( 'wp-theme-plugin-editor' ); 1142 1143 $scripts->add( 'wp-playlist', "/wp-includes/js/mediaelement/wp-playlist$suffix.js", array( 'wp-util', 'backbone', 'mediaelement' ), false, 1 ); 1144 1145 $scripts->add( 'zxcvbn-async', "/wp-includes/js/zxcvbn-async$suffix.js", array(), '1.0' ); 1146 did_action( 'init' ) && $scripts->localize( 1147 'zxcvbn-async', 1148 '_zxcvbnSettings', 1149 array( 1150 'src' => empty( $guessed_url ) ? includes_url( '/js/zxcvbn.min.js' ) : $scripts->base_url . '/wp-includes/js/zxcvbn.min.js', 1151 ) 1152 ); 1153 1154 $scripts->add( 'password-strength-meter', "/wp-admin/js/password-strength-meter$suffix.js", array( 'jquery', 'zxcvbn-async' ), false, 1 ); 1155 did_action( 'init' ) && $scripts->localize( 1156 'password-strength-meter', 1157 'pwsL10n', 1158 array( 1159 'unknown' => _x( 'Password strength unknown', 'password strength' ), 1160 'short' => _x( 'Very weak', 'password strength' ), 1161 'bad' => _x( 'Weak', 'password strength' ), 1162 'good' => _x( 'Medium', 'password strength' ), 1163 'strong' => _x( 'Strong', 'password strength' ), 1164 'mismatch' => _x( 'Mismatch', 'password mismatch' ), 1165 ) 1166 ); 1167 $scripts->set_translations( 'password-strength-meter' ); 1168 1169 $scripts->add( 'application-passwords', "/wp-admin/js/application-passwords$suffix.js", array( 'jquery', 'wp-util', 'wp-api-request', 'wp-date', 'wp-i18n', 'wp-hooks' ), false, 1 ); 1170 $scripts->set_translations( 'application-passwords' ); 1171 1172 $scripts->add( 'auth-app', "/wp-admin/js/auth-app$suffix.js", array( 'jquery', 'wp-api-request', 'wp-i18n', 'wp-hooks' ), false, 1 ); 1173 $scripts->set_translations( 'auth-app' ); 1174 1175 $scripts->add( 'user-profile', "/wp-admin/js/user-profile$suffix.js", array( 'jquery', 'password-strength-meter', 'wp-util' ), false, 1 ); 1176 $scripts->set_translations( 'user-profile' ); 1177 $user_id = isset( $_GET['user_id'] ) ? (int) $_GET['user_id'] : 0; 1178 did_action( 'init' ) && $scripts->localize( 1179 'user-profile', 1180 'userProfileL10n', 1181 array( 1182 'user_id' => $user_id, 1183 'nonce' => wp_installing() ? '' : wp_create_nonce( 'reset-password-for-' . $user_id ), 1184 ) 1185 ); 1186 1187 $scripts->add( 'language-chooser', "/wp-admin/js/language-chooser$suffix.js", array( 'jquery' ), false, 1 ); 1188 1189 $scripts->add( 'user-suggest', "/wp-admin/js/user-suggest$suffix.js", array( 'jquery-ui-autocomplete' ), false, 1 ); 1190 1191 $scripts->add( 'admin-bar', "/wp-includes/js/admin-bar$suffix.js", array( 'hoverintent-js' ), false, 1 ); 1192 1193 $scripts->add( 'wplink', "/wp-includes/js/wplink$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 ); 1194 did_action( 'init' ) && $scripts->localize( 1195 'wplink', 1196 'wpLinkL10n', 1197 array( 1198 'title' => __( 'Insert/edit link' ), 1199 'update' => __( 'Update' ), 1200 'save' => __( 'Add Link' ), 1201 'noTitle' => __( '(no title)' ), 1202 'noMatchesFound' => __( 'No results found.' ), 1203 'linkSelected' => __( 'Link selected.' ), 1204 'linkInserted' => __( 'Link inserted.' ), 1205 /* translators: Minimum input length in characters to start searching posts in the "Insert/edit link" modal. */ 1206 'minInputLength' => (int) _x( '3', 'minimum input length for searching post links' ), 1207 ) 1208 ); 1209 1210 $scripts->add( 'wpdialogs', "/wp-includes/js/wpdialog$suffix.js", array( 'jquery-ui-dialog' ), false, 1 ); 1211 1212 $scripts->add( 'word-count', "/wp-admin/js/word-count$suffix.js", array(), false, 1 ); 1213 1214 $scripts->add( 'media-upload', "/wp-admin/js/media-upload$suffix.js", array( 'thickbox', 'shortcode' ), false, 1 ); 1215 1216 $scripts->add( 'hoverIntent', "/wp-includes/js/hoverIntent$suffix.js", array( 'jquery' ), '1.10.2', 1 ); 1217 1218 // JS-only version of hoverintent (no dependencies). 1219 $scripts->add( 'hoverintent-js', '/wp-includes/js/hoverintent-js.min.js', array(), '2.2.1', 1 ); 1220 1221 $scripts->add( 'customize-base', "/wp-includes/js/customize-base$suffix.js", array( 'jquery', 'json2', 'underscore' ), false, 1 ); 1222 $scripts->add( 'customize-loader', "/wp-includes/js/customize-loader$suffix.js", array( 'customize-base' ), false, 1 ); 1223 $scripts->add( 'customize-preview', "/wp-includes/js/customize-preview$suffix.js", array( 'wp-a11y', 'customize-base' ), false, 1 ); 1224 $scripts->add( 'customize-models', '/wp-includes/js/customize-models.js', array( 'underscore', 'backbone' ), false, 1 ); 1225 $scripts->add( 'customize-views', '/wp-includes/js/customize-views.js', array( 'jquery', 'underscore', 'imgareaselect', 'customize-models', 'media-editor', 'media-views' ), false, 1 ); 1226 $scripts->add( 'customize-controls', "/wp-admin/js/customize-controls$suffix.js", array( 'customize-base', 'wp-a11y', 'wp-util', 'jquery-ui-core' ), false, 1 ); 1227 did_action( 'init' ) && $scripts->localize( 1228 'customize-controls', 1229 '_wpCustomizeControlsL10n', 1230 array( 1231 'activate' => __( 'Activate & Publish' ), 1232 'save' => __( 'Save & Publish' ), // @todo Remove as not required. 1233 'publish' => __( 'Publish' ), 1234 'published' => __( 'Published' ), 1235 'saveDraft' => __( 'Save Draft' ), 1236 'draftSaved' => __( 'Draft Saved' ), 1237 'updating' => __( 'Updating' ), 1238 'schedule' => _x( 'Schedule', 'customizer changeset action/button label' ), 1239 'scheduled' => _x( 'Scheduled', 'customizer changeset status' ), 1240 'invalid' => __( 'Invalid' ), 1241 'saveBeforeShare' => __( 'Please save your changes in order to share the preview.' ), 1242 'futureDateError' => __( 'You must supply a future date to schedule.' ), 1243 'saveAlert' => __( 'The changes you made will be lost if you navigate away from this page.' ), 1244 'saved' => __( 'Saved' ), 1245 'cancel' => __( 'Cancel' ), 1246 'close' => __( 'Close' ), 1247 'action' => __( 'Action' ), 1248 'discardChanges' => __( 'Discard changes' ), 1249 'cheatin' => __( 'Something went wrong.' ), 1250 'notAllowedHeading' => __( 'You need a higher level of permission.' ), 1251 'notAllowed' => __( 'Sorry, you are not allowed to customize this site.' ), 1252 'previewIframeTitle' => __( 'Site Preview' ), 1253 'loginIframeTitle' => __( 'Session expired' ), 1254 'collapseSidebar' => _x( 'Hide Controls', 'label for hide controls button without length constraints' ), 1255 'expandSidebar' => _x( 'Show Controls', 'label for hide controls button without length constraints' ), 1256 'untitledBlogName' => __( '(Untitled)' ), 1257 'unknownRequestFail' => __( 'Looks like something’s gone wrong. Wait a couple seconds, and then try again.' ), 1258 'themeDownloading' => __( 'Downloading your new theme…' ), 1259 'themePreviewWait' => __( 'Setting up your live preview. This may take a bit.' ), 1260 'revertingChanges' => __( 'Reverting unpublished changes…' ), 1261 'trashConfirm' => __( 'Are you sure you want to discard your unpublished changes?' ), 1262 /* translators: %s: Display name of the user who has taken over the changeset in customizer. */ 1263 'takenOverMessage' => __( '%s has taken over and is currently customizing.' ), 1264 /* translators: %s: URL to the Customizer to load the autosaved version. */ 1265 'autosaveNotice' => __( 'There is a more recent autosave of your changes than the one you are previewing. <a href="%s">Restore the autosave</a>' ), 1266 'videoHeaderNotice' => __( 'This theme does not support video headers on this page. Navigate to the front page or another page that supports video headers.' ), 1267 // Used for overriding the file types allowed in Plupload. 1268 'allowedFiles' => __( 'Allowed Files' ), 1269 'customCssError' => array( 1270 /* translators: %d: Error count. */ 1271 'singular' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 1 ), 1272 /* translators: %d: Error count. */ 1273 'plural' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 2 ), 1274 // @todo This is lacking, as some languages have a dedicated dual form. For proper handling of plurals in JS, see #20491. 1275 ), 1276 'pageOnFrontError' => __( 'Homepage and posts page must be different.' ), 1277 'saveBlockedError' => array( 1278 /* translators: %s: Number of invalid settings. */ 1279 'singular' => _n( 'Unable to save due to %s invalid setting.', 'Unable to save due to %s invalid settings.', 1 ), 1280 /* translators: %s: Number of invalid settings. */ 1281 'plural' => _n( 'Unable to save due to %s invalid setting.', 'Unable to save due to %s invalid settings.', 2 ), 1282 // @todo This is lacking, as some languages have a dedicated dual form. For proper handling of plurals in JS, see #20491. 1283 ), 1284 'scheduleDescription' => __( 'Schedule your customization changes to publish ("go live") at a future date.' ), 1285 'themePreviewUnavailable' => __( 'Sorry, you cannot preview new themes when you have changes scheduled or saved as a draft. Please publish your changes, or wait until they publish to preview new themes.' ), 1286 'themeInstallUnavailable' => sprintf( 1287 /* translators: %s: URL to Add Themes admin screen. */ 1288 __( 'You will not be able to install new themes from here yet since your install requires SFTP credentials. For now, please <a href="%s">add themes in the admin</a>.' ), 1289 esc_url( admin_url( 'theme-install.php' ) ) 1290 ), 1291 'publishSettings' => __( 'Publish Settings' ), 1292 'invalidDate' => __( 'Invalid date.' ), 1293 'invalidValue' => __( 'Invalid value.' ), 1294 'blockThemeNotification' => sprintf( 1295 /* translators: 1: Link to Site Editor documentation on HelpHub, 2: HTML button. */ 1296 __( 'Hurray! Your theme supports site editing with blocks. <a href="%1$s">Tell me more</a>. %2$s' ), 1297 __( 'https://wordpress.org/documentation/article/site-editor/' ), 1298 sprintf( 1299 '<button type="button" data-action="%1$s" class="button switch-to-editor">%2$s</button>', 1300 esc_url( admin_url( 'site-editor.php' ) ), 1301 __( 'Use Site Editor' ) 1302 ) 1303 ), 1304 ) 1305 ); 1306 $scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 ); 1307 1308 $scripts->add( 'customize-widgets', "/wp-admin/js/customize-widgets$suffix.js", array( 'jquery', 'jquery-ui-sortable', 'jquery-ui-droppable', 'wp-backbone', 'customize-controls' ), false, 1 ); 1309 $scripts->add( 'customize-preview-widgets', "/wp-includes/js/customize-preview-widgets$suffix.js", array( 'jquery', 'wp-util', 'customize-preview', 'customize-selective-refresh' ), false, 1 ); 1310 1311 $scripts->add( 'customize-nav-menus', "/wp-admin/js/customize-nav-menus$suffix.js", array( 'jquery', 'wp-backbone', 'customize-controls', 'accordion', 'nav-menu', 'wp-sanitize' ), false, 1 ); 1312 $scripts->add( 'customize-preview-nav-menus', "/wp-includes/js/customize-preview-nav-menus$suffix.js", array( 'jquery', 'wp-util', 'customize-preview', 'customize-selective-refresh' ), false, 1 ); 1313 1314 $scripts->add( 'wp-custom-header', "/wp-includes/js/wp-custom-header$suffix.js", array( 'wp-a11y' ), false, 1 ); 1315 1316 $scripts->add( 'accordion', "/wp-admin/js/accordion$suffix.js", array( 'jquery' ), false, 1 ); 1317 1318 $scripts->add( 'shortcode', "/wp-includes/js/shortcode$suffix.js", array( 'underscore' ), false, 1 ); 1319 $scripts->add( 'media-models', "/wp-includes/js/media-models$suffix.js", array( 'wp-backbone' ), false, 1 ); 1320 did_action( 'init' ) && $scripts->localize( 1321 'media-models', 1322 '_wpMediaModelsL10n', 1323 array( 1324 'settings' => array( 1325 'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), 1326 'post' => array( 'id' => 0 ), 1327 ), 1328 ) 1329 ); 1330 1331 $scripts->add( 'wp-embed', "/wp-includes/js/wp-embed$suffix.js", array(), false, 1 ); 1332 1333 // To enqueue media-views or media-editor, call wp_enqueue_media(). 1334 // Both rely on numerous settings, styles, and templates to operate correctly. 1335 $scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable', 'wp-mediaelement', 'wp-api-request', 'wp-a11y', 'clipboard' ), false, 1 ); 1336 $scripts->set_translations( 'media-views' ); 1337 1338 $scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views' ), false, 1 ); 1339 $scripts->set_translations( 'media-editor' ); 1340 $scripts->add( 'media-audiovideo', "/wp-includes/js/media-audiovideo$suffix.js", array( 'media-editor' ), false, 1 ); 1341 $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'jquery', 'media-views', 'media-audiovideo' ), false, 1 ); 1342 1343 $scripts->add( 'wp-api', "/wp-includes/js/wp-api$suffix.js", array( 'jquery', 'backbone', 'underscore', 'wp-api-request' ), false, 1 ); 1344 1345 if ( is_admin() ) { 1346 $scripts->add( 'admin-tags', "/wp-admin/js/tags$suffix.js", array( 'jquery', 'wp-ajax-response' ), false, 1 ); 1347 $scripts->set_translations( 'admin-tags' ); 1348 1349 $scripts->add( 'admin-comments', "/wp-admin/js/edit-comments$suffix.js", array( 'wp-lists', 'quicktags', 'jquery-query' ), false, 1 ); 1350 $scripts->set_translations( 'admin-comments' ); 1351 did_action( 'init' ) && $scripts->localize( 1352 'admin-comments', 1353 'adminCommentsSettings', 1354 array( 1355 'hotkeys_highlight_first' => isset( $_GET['hotkeys_highlight_first'] ), 1356 'hotkeys_highlight_last' => isset( $_GET['hotkeys_highlight_last'] ), 1357 ) 1358 ); 1359 1360 $scripts->add( 'xfn', "/wp-admin/js/xfn$suffix.js", array( 'jquery' ), false, 1 ); 1361 1362 $scripts->add( 'postbox', "/wp-admin/js/postbox$suffix.js", array( 'jquery-ui-sortable', 'wp-a11y' ), false, 1 ); 1363 $scripts->set_translations( 'postbox' ); 1364 1365 $scripts->add( 'tags-box', "/wp-admin/js/tags-box$suffix.js", array( 'jquery', 'tags-suggest' ), false, 1 ); 1366 $scripts->set_translations( 'tags-box' ); 1367 1368 $scripts->add( 'tags-suggest', "/wp-admin/js/tags-suggest$suffix.js", array( 'jquery-ui-autocomplete', 'wp-a11y' ), false, 1 ); 1369 $scripts->set_translations( 'tags-suggest' ); 1370 1371 $scripts->add( 'post', "/wp-admin/js/post$suffix.js", array( 'suggest', 'wp-lists', 'postbox', 'tags-box', 'underscore', 'word-count', 'wp-a11y', 'wp-sanitize', 'clipboard' ), false, 1 ); 1372 $scripts->set_translations( 'post' ); 1373 1374 $scripts->add( 'editor-expand', "/wp-admin/js/editor-expand$suffix.js", array( 'jquery', 'underscore' ), false, 1 ); 1375 1376 $scripts->add( 'link', "/wp-admin/js/link$suffix.js", array( 'wp-lists', 'postbox' ), false, 1 ); 1377 1378 $scripts->add( 'comment', "/wp-admin/js/comment$suffix.js", array( 'jquery', 'postbox' ), false, 1 ); 1379 $scripts->set_translations( 'comment' ); 1380 1381 $scripts->add( 'admin-gallery', "/wp-admin/js/gallery$suffix.js", array( 'jquery-ui-sortable' ) ); 1382 1383 $scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'wp-a11y' ), false, 1 ); 1384 $scripts->set_translations( 'admin-widgets' ); 1385 1386 $scripts->add( 'media-widgets', "/wp-admin/js/widgets/media-widgets$suffix.js", array( 'jquery', 'media-models', 'media-views', 'wp-api-request' ) ); 1387 $scripts->add_inline_script( 'media-widgets', 'wp.mediaWidgets.init();', 'after' ); 1388 1389 $scripts->add( 'media-audio-widget', "/wp-admin/js/widgets/media-audio-widget$suffix.js", array( 'media-widgets', 'media-audiovideo' ) ); 1390 $scripts->add( 'media-image-widget', "/wp-admin/js/widgets/media-image-widget$suffix.js", array( 'media-widgets' ) ); 1391 $scripts->add( 'media-gallery-widget', "/wp-admin/js/widgets/media-gallery-widget$suffix.js", array( 'media-widgets' ) ); 1392 $scripts->add( 'media-video-widget', "/wp-admin/js/widgets/media-video-widget$suffix.js", array( 'media-widgets', 'media-audiovideo', 'wp-api-request' ) ); 1393 $scripts->add( 'text-widgets', "/wp-admin/js/widgets/text-widgets$suffix.js", array( 'jquery', 'backbone', 'editor', 'wp-util', 'wp-a11y' ) ); 1394 $scripts->add( 'custom-html-widgets', "/wp-admin/js/widgets/custom-html-widgets$suffix.js", array( 'jquery', 'backbone', 'wp-util', 'jquery-ui-core', 'wp-a11y' ) ); 1395 1396 $scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'wp-backbone', 'wp-a11y', 'customize-base' ), false, 1 ); 1397 1398 $scripts->add( 'inline-edit-post', "/wp-admin/js/inline-edit-post$suffix.js", array( 'jquery', 'tags-suggest', 'wp-a11y' ), false, 1 ); 1399 $scripts->set_translations( 'inline-edit-post' ); 1400 1401 $scripts->add( 'inline-edit-tax', "/wp-admin/js/inline-edit-tax$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 ); 1402 $scripts->set_translations( 'inline-edit-tax' ); 1403 1404 $scripts->add( 'plugin-install', "/wp-admin/js/plugin-install$suffix.js", array( 'jquery', 'jquery-ui-core', 'thickbox' ), false, 1 ); 1405 $scripts->set_translations( 'plugin-install' ); 1406 1407 $scripts->add( 'site-health', "/wp-admin/js/site-health$suffix.js", array( 'clipboard', 'jquery', 'wp-util', 'wp-a11y', 'wp-api-request', 'wp-url', 'wp-i18n', 'wp-hooks' ), false, 1 ); 1408 $scripts->set_translations( 'site-health' ); 1409 1410 $scripts->add( 'privacy-tools', "/wp-admin/js/privacy-tools$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 ); 1411 $scripts->set_translations( 'privacy-tools' ); 1412 1413 $scripts->add( 'updates', "/wp-admin/js/updates$suffix.js", array( 'common', 'jquery', 'wp-util', 'wp-a11y', 'wp-sanitize', 'wp-i18n' ), false, 1 ); 1414 $scripts->set_translations( 'updates' ); 1415 did_action( 'init' ) && $scripts->localize( 1416 'updates', 1417 '_wpUpdatesSettings', 1418 array( 1419 'ajax_nonce' => wp_installing() ? '' : wp_create_nonce( 'updates' ), 1420 ) 1421 ); 1422 1423 $scripts->add( 'farbtastic', '/wp-admin/js/farbtastic.js', array( 'jquery' ), '1.2' ); 1424 1425 $scripts->add( 'iris', '/wp-admin/js/iris.min.js', array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), '1.1.1', 1 ); 1426 $scripts->add( 'wp-color-picker', "/wp-admin/js/color-picker$suffix.js", array( 'iris' ), false, 1 ); 1427 $scripts->set_translations( 'wp-color-picker' ); 1428 1429 $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-util', 'wp-a11y', 'wp-date' ), false, 1 ); 1430 $scripts->set_translations( 'dashboard' ); 1431 1432 $scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" ); 1433 1434 $scripts->add( 'media-grid', "/wp-includes/js/media-grid$suffix.js", array( 'media-editor' ), false, 1 ); 1435 $scripts->add( 'media', "/wp-admin/js/media$suffix.js", array( 'jquery', 'clipboard', 'wp-i18n', 'wp-a11y' ), false, 1 ); 1436 $scripts->set_translations( 'media' ); 1437 1438 $scripts->add( 'image-edit', "/wp-admin/js/image-edit$suffix.js", array( 'jquery', 'jquery-ui-core', 'json2', 'imgareaselect', 'wp-a11y' ), false, 1 ); 1439 $scripts->set_translations( 'image-edit' ); 1440 1441 $scripts->add( 'set-post-thumbnail', "/wp-admin/js/set-post-thumbnail$suffix.js", array( 'jquery' ), false, 1 ); 1442 $scripts->set_translations( 'set-post-thumbnail' ); 1443 1444 /* 1445 * Navigation Menus: Adding underscore as a dependency to utilize _.debounce 1446 * see https://core.trac.wordpress.org/ticket/42321 1447 */ 1448 $scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'wp-lists', 'postbox', 'json2', 'underscore' ) ); 1449 $scripts->set_translations( 'nav-menu' ); 1450 1451 $scripts->add( 'custom-header', '/wp-admin/js/custom-header.js', array( 'jquery-masonry' ), false, 1 ); 1452 $scripts->add( 'custom-background', "/wp-admin/js/custom-background$suffix.js", array( 'wp-color-picker', 'media-views' ), false, 1 ); 1453 $scripts->add( 'media-gallery', "/wp-admin/js/media-gallery$suffix.js", array( 'jquery' ), false, 1 ); 1454 1455 $scripts->add( 'svg-painter', '/wp-admin/js/svg-painter.js', array( 'jquery' ), false, 1 ); 1456 } 1457 } 1458 1459 /** 1460 * Assigns default styles to $styles object. 1461 * 1462 * Nothing is returned, because the $styles parameter is passed by reference. 1463 * Meaning that whatever object is passed will be updated without having to 1464 * reassign the variable that was passed back to the same value. This saves 1465 * memory. 1466 * 1467 * Adding default styles is not the only task, it also assigns the base_url 1468 * property, the default version, and text direction for the object. 1469 * 1470 * @since 2.6.0 1471 * 1472 * @global array $editor_styles 1473 * 1474 * @param WP_Styles $styles 1475 */ 1476 function wp_default_styles( $styles ) { 1477 global $editor_styles; 1478 1479 // Include an unmodified $wp_version. 1480 require ABSPATH . WPINC . '/version.php'; 1481 1482 if ( ! defined( 'SCRIPT_DEBUG' ) ) { 1483 define( 'SCRIPT_DEBUG', false !== strpos( $wp_version, '-src' ) ); 1484 } 1485 1486 $guessurl = site_url(); 1487 1488 if ( ! $guessurl ) { 1489 $guessurl = wp_guess_url(); 1490 } 1491 1492 $styles->base_url = $guessurl; 1493 $styles->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : ''; 1494 $styles->default_version = get_bloginfo( 'version' ); 1495 $styles->text_direction = function_exists( 'is_rtl' ) && is_rtl() ? 'rtl' : 'ltr'; 1496 $styles->default_dirs = array( '/wp-admin/', '/wp-includes/css/' ); 1497 1498 // Open Sans is no longer used by core, but may be relied upon by themes and plugins. 1499 $open_sans_font_url = ''; 1500 1501 /* 1502 * translators: If there are characters in your language that are not supported 1503 * by Open Sans, translate this to 'off'. Do not translate into your own language. 1504 */ 1505 if ( 'off' !== _x( 'on', 'Open Sans font: on or off' ) ) { 1506 $subsets = 'latin,latin-ext'; 1507 1508 /* 1509 * translators: To add an additional Open Sans character subset specific to your language, 1510 * translate this to 'greek', 'cyrillic' or 'vietnamese'. Do not translate into your own language. 1511 */ 1512 $subset = _x( 'no-subset', 'Open Sans font: add new subset (greek, cyrillic, vietnamese)' ); 1513 1514 if ( 'cyrillic' === $subset ) { 1515 $subsets .= ',cyrillic,cyrillic-ext'; 1516 } elseif ( 'greek' === $subset ) { 1517 $subsets .= ',greek,greek-ext'; 1518 } elseif ( 'vietnamese' === $subset ) { 1519 $subsets .= ',vietnamese'; 1520 } 1521 1522 // Hotlink Open Sans, for now. 1523 $open_sans_font_url = "https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,300,400,600&subset=$subsets&display=fallback"; 1524 } 1525 1526 // Register a stylesheet for the selected admin color scheme. 1527 $styles->add( 'colors', true, array( 'wp-admin', 'buttons' ) ); 1528 1529 $suffix = SCRIPT_DEBUG ? '' : '.min'; 1530 1531 // Admin CSS. 1532 $styles->add( 'common', "/wp-admin/css/common$suffix.css" ); 1533 $styles->add( 'forms', "/wp-admin/css/forms$suffix.css" ); 1534 $styles->add( 'admin-menu', "/wp-admin/css/admin-menu$suffix.css" ); 1535 $styles->add( 'dashboard', "/wp-admin/css/dashboard$suffix.css" ); 1536 $styles->add( 'list-tables', "/wp-admin/css/list-tables$suffix.css" ); 1537 $styles->add( 'edit', "/wp-admin/css/edit$suffix.css" ); 1538 $styles->add( 'revisions', "/wp-admin/css/revisions$suffix.css" ); 1539 $styles->add( 'media', "/wp-admin/css/media$suffix.css" ); 1540 $styles->add( 'themes', "/wp-admin/css/themes$suffix.css" ); 1541 $styles->add( 'about', "/wp-admin/css/about$suffix.css" ); 1542 $styles->add( 'nav-menus', "/wp-admin/css/nav-menus$suffix.css" ); 1543 $styles->add( 'widgets', "/wp-admin/css/widgets$suffix.css", array( 'wp-pointer' ) ); 1544 $styles->add( 'site-icon', "/wp-admin/css/site-icon$suffix.css" ); 1545 $styles->add( 'l10n', "/wp-admin/css/l10n$suffix.css" ); 1546 $styles->add( 'code-editor', "/wp-admin/css/code-editor$suffix.css", array( 'wp-codemirror' ) ); 1547 $styles->add( 'site-health', "/wp-admin/css/site-health$suffix.css" ); 1548 1549 $styles->add( 'wp-admin', false, array( 'dashicons', 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n' ) ); 1550 1551 $styles->add( 'login', "/wp-admin/css/login$suffix.css", array( 'dashicons', 'buttons', 'forms', 'l10n' ) ); 1552 $styles->add( 'install', "/wp-admin/css/install$suffix.css", array( 'dashicons', 'buttons', 'forms', 'l10n' ) ); 1553 $styles->add( 'wp-color-picker', "/wp-admin/css/color-picker$suffix.css" ); 1554 $styles->add( 'customize-controls', "/wp-admin/css/customize-controls$suffix.css", array( 'wp-admin', 'colors', 'imgareaselect' ) ); 1555 $styles->add( 'customize-widgets', "/wp-admin/css/customize-widgets$suffix.css", array( 'wp-admin', 'colors' ) ); 1556 $styles->add( 'customize-nav-menus', "/wp-admin/css/customize-nav-menus$suffix.css", array( 'wp-admin', 'colors' ) ); 1557 1558 // Common dependencies. 1559 $styles->add( 'buttons', "/wp-includes/css/buttons$suffix.css" ); 1560 $styles->add( 'dashicons', "/wp-includes/css/dashicons$suffix.css" ); 1561 1562 // Includes CSS. 1563 $styles->add( 'admin-bar', "/wp-includes/css/admin-bar$suffix.css", array( 'dashicons' ) ); 1564 $styles->add( 'wp-auth-check', "/wp-includes/css/wp-auth-check$suffix.css", array( 'dashicons' ) ); 1565 $styles->add( 'editor-buttons', "/wp-includes/css/editor$suffix.css", array( 'dashicons' ) ); 1566 $styles->add( 'media-views', "/wp-includes/css/media-views$suffix.css", array( 'buttons', 'dashicons', 'wp-mediaelement' ) ); 1567 $styles->add( 'wp-pointer', "/wp-includes/css/wp-pointer$suffix.css", array( 'dashicons' ) ); 1568 $styles->add( 'customize-preview', "/wp-includes/css/customize-preview$suffix.css", array( 'dashicons' ) ); 1569 $styles->add( 'wp-embed-template-ie', "/wp-includes/css/wp-embed-template-ie$suffix.css" ); 1570 $styles->add_data( 'wp-embed-template-ie', 'conditional', 'lte IE 8' ); 1571 1572 // External libraries and friends. 1573 $styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.8' ); 1574 $styles->add( 'wp-jquery-ui-dialog', "/wp-includes/css/jquery-ui-dialog$suffix.css", array( 'dashicons' ) ); 1575 $styles->add( 'mediaelement', '/wp-includes/js/mediaelement/mediaelementplayer-legacy.min.css', array(), '4.2.17' ); 1576 $styles->add( 'wp-mediaelement', "/wp-includes/js/mediaelement/wp-mediaelement$suffix.css", array( 'mediaelement' ) ); 1577 $styles->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.css', array( 'dashicons' ) ); 1578 $styles->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.css', array(), '5.29.1-alpha-ee20357' ); 1579 1580 // Deprecated CSS. 1581 $styles->add( 'deprecated-media', "/wp-admin/css/deprecated-media$suffix.css" ); 1582 $styles->add( 'farbtastic', "/wp-admin/css/farbtastic$suffix.css", array(), '1.3u1' ); 1583 $styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.min.css', array(), '0.9.15' ); 1584 $styles->add( 'colors-fresh', false, array( 'wp-admin', 'buttons' ) ); // Old handle. 1585 $styles->add( 'open-sans', $open_sans_font_url ); // No longer used in core as of 4.6. 1586 1587 // Noto Serif is no longer used by core, but may be relied upon by themes and plugins. 1588 $fonts_url = ''; 1589 1590 /* 1591 * translators: Use this to specify the proper Google Font name and variants 1592 * to load that is supported by your language. Do not translate. 1593 * Set to 'off' to disable loading. 1594 */ 1595 $font_family = _x( 'Noto Serif:400,400i,700,700i', 'Google Font Name and Variants' ); 1596 if ( 'off' !== $font_family ) { 1597 $fonts_url = 'https://fonts.googleapis.com/css?family=' . urlencode( $font_family ); 1598 } 1599 $styles->add( 'wp-editor-font', $fonts_url ); // No longer used in core as of 5.7. 1600 $block_library_theme_path = WPINC . "/css/dist/block-library/theme$suffix.css"; 1601 $styles->add( 'wp-block-library-theme', "/$block_library_theme_path" ); 1602 $styles->add_data( 'wp-block-library-theme', 'path', ABSPATH . $block_library_theme_path ); 1603 1604 $styles->add( 1605 'wp-reset-editor-styles', 1606 "/wp-includes/css/dist/block-library/reset$suffix.css", 1607 array( 'common', 'forms' ) // Make sure the reset is loaded after the default WP Admin styles. 1608 ); 1609 1610 $styles->add( 1611 'wp-editor-classic-layout-styles', 1612 "/wp-includes/css/dist/edit-post/classic$suffix.css", 1613 array() 1614 ); 1615 1616 $styles->add( 1617 'wp-block-editor-content', 1618 "/wp-includes/css/dist/block-editor/content$suffix.css", 1619 array() 1620 ); 1621 1622 $wp_edit_blocks_dependencies = array( 1623 'wp-components', 1624 'wp-editor', 1625 // This need to be added before the block library styles, 1626 // The block library styles override the "reset" styles. 1627 'wp-reset-editor-styles', 1628 'wp-block-library', 1629 'wp-reusable-blocks', 1630 'wp-block-editor-content', 1631 ); 1632 1633 // Only load the default layout and margin styles for themes without theme.json file. 1634 if ( ! wp_theme_has_theme_json() ) { 1635 $wp_edit_blocks_dependencies[] = 'wp-editor-classic-layout-styles'; 1636 } 1637 1638 if ( 1639 current_theme_supports( 'wp-block-styles' ) && 1640 ( ! is_array( $editor_styles ) || count( $editor_styles ) === 0 ) 1641 ) { 1642 /* 1643 * Include opinionated block styles if the theme supports block styles and 1644 * no $editor_styles are declared, so the editor never appears broken. 1645 */ 1646 $wp_edit_blocks_dependencies[] = 'wp-block-library-theme'; 1647 } 1648 1649 $styles->add( 1650 'wp-edit-blocks', 1651 "/wp-includes/css/dist/block-library/editor$suffix.css", 1652 $wp_edit_blocks_dependencies 1653 ); 1654 1655 $package_styles = array( 1656 'block-editor' => array( 'wp-components' ), 1657 'block-library' => array(), 1658 'block-directory' => array(), 1659 'components' => array(), 1660 'edit-post' => array( 1661 'wp-components', 1662 'wp-block-editor', 1663 'wp-editor', 1664 'wp-edit-blocks', 1665 'wp-block-library', 1666 ), 1667 'editor' => array( 1668 'wp-components', 1669 'wp-block-editor', 1670 'wp-reusable-blocks', 1671 ), 1672 'format-library' => array(), 1673 'list-reusable-blocks' => array( 'wp-components' ), 1674 'reusable-blocks' => array( 'wp-components' ), 1675 'nux' => array( 'wp-components' ), 1676 'widgets' => array( 1677 'wp-components', 1678 ), 1679 'edit-widgets' => array( 1680 'wp-widgets', 1681 'wp-block-editor', 1682 'wp-edit-blocks', 1683 'wp-block-library', 1684 'wp-reusable-blocks', 1685 ), 1686 'customize-widgets' => array( 1687 'wp-widgets', 1688 'wp-block-editor', 1689 'wp-edit-blocks', 1690 'wp-block-library', 1691 'wp-reusable-blocks', 1692 ), 1693 'edit-site' => array( 1694 'wp-components', 1695 'wp-block-editor', 1696 'wp-edit-blocks', 1697 ), 1698 ); 1699 1700 foreach ( $package_styles as $package => $dependencies ) { 1701 $handle = 'wp-' . $package; 1702 $path = "/wp-includes/css/dist/$package/style$suffix.css"; 1703 1704 if ( 'block-library' === $package && wp_should_load_separate_core_block_assets() ) { 1705 $path = "/wp-includes/css/dist/$package/common$suffix.css"; 1706 } 1707 $styles->add( $handle, $path, $dependencies ); 1708 $styles->add_data( $handle, 'path', ABSPATH . $path ); 1709 } 1710 1711 // RTL CSS. 1712 $rtl_styles = array( 1713 // Admin CSS. 1714 'common', 1715 'forms', 1716 'admin-menu', 1717 'dashboard', 1718 'list-tables', 1719 'edit', 1720 'revisions', 1721 'media', 1722 'themes', 1723 'about', 1724 'nav-menus', 1725 'widgets', 1726 'site-icon', 1727 'l10n', 1728 'install', 1729 'wp-color-picker', 1730 'customize-controls', 1731 'customize-widgets', 1732 'customize-nav-menus', 1733 'customize-preview', 1734 'login', 1735 'site-health', 1736 // Includes CSS. 1737 'buttons', 1738 'admin-bar', 1739 'wp-auth-check', 1740 'editor-buttons', 1741 'media-views', 1742 'wp-pointer', 1743 'wp-jquery-ui-dialog', 1744 // Package styles. 1745 'wp-reset-editor-styles', 1746 'wp-editor-classic-layout-styles', 1747 'wp-block-library-theme', 1748 'wp-edit-blocks', 1749 'wp-block-editor', 1750 'wp-block-library', 1751 'wp-block-directory', 1752 'wp-components', 1753 'wp-customize-widgets', 1754 'wp-edit-post', 1755 'wp-edit-site', 1756 'wp-edit-widgets', 1757 'wp-editor', 1758 'wp-format-library', 1759 'wp-list-reusable-blocks', 1760 'wp-reusable-blocks', 1761 'wp-nux', 1762 'wp-widgets', 1763 // Deprecated CSS. 1764 'deprecated-media', 1765 'farbtastic', 1766 ); 1767 1768 foreach ( $rtl_styles as $rtl_style ) { 1769 $styles->add_data( $rtl_style, 'rtl', 'replace' ); 1770 if ( $suffix ) { 1771 $styles->add_data( $rtl_style, 'suffix', $suffix ); 1772 } 1773 } 1774 } 1775 1776 /** 1777 * Reorders JavaScript scripts array to place prototype before jQuery. 1778 * 1779 * @since 2.3.1 1780 * 1781 * @param string[] $js_array JavaScript scripts array 1782 * @return string[] Reordered array, if needed. 1783 */ 1784 function wp_prototype_before_jquery( $js_array ) { 1785 $prototype = array_search( 'prototype', $js_array, true ); 1786 1787 if ( false === $prototype ) { 1788 return $js_array; 1789 } 1790 1791 $jquery = array_search( 'jquery', $js_array, true ); 1792 1793 if ( false === $jquery ) { 1794 return $js_array; 1795 } 1796 1797 if ( $prototype < $jquery ) { 1798 return $js_array; 1799 } 1800 1801 unset( $js_array[ $prototype ] ); 1802 1803 array_splice( $js_array, $jquery, 0, 'prototype' ); 1804 1805 return $js_array; 1806 } 1807 1808 /** 1809 * Loads localized data on print rather than initialization. 1810 * 1811 * These localizations require information that may not be loaded even by init. 1812 * 1813 * @since 2.5.0 1814 */ 1815 function wp_just_in_time_script_localization() { 1816 1817 wp_localize_script( 1818 'autosave', 1819 'autosaveL10n', 1820 array( 1821 'autosaveInterval' => AUTOSAVE_INTERVAL, 1822 'blog_id' => get_current_blog_id(), 1823 ) 1824 ); 1825 1826 wp_localize_script( 1827 'mce-view', 1828 'mceViewL10n', 1829 array( 1830 'shortcodes' => ! empty( $GLOBALS['shortcode_tags'] ) ? array_keys( $GLOBALS['shortcode_tags'] ) : array(), 1831 ) 1832 ); 1833 1834 wp_localize_script( 1835 'word-count', 1836 'wordCountL10n', 1837 array( 1838 'type' => wp_get_word_count_type(), 1839 'shortcodes' => ! empty( $GLOBALS['shortcode_tags'] ) ? array_keys( $GLOBALS['shortcode_tags'] ) : array(), 1840 ) 1841 ); 1842 } 1843 1844 /** 1845 * Localizes the jQuery UI datepicker. 1846 * 1847 * @since 4.6.0 1848 * 1849 * @link https://api.jqueryui.com/datepicker/#options 1850 * 1851 * @global WP_Locale $wp_locale WordPress date and time locale object. 1852 */ 1853 function wp_localize_jquery_ui_datepicker() { 1854 global $wp_locale; 1855 1856 if ( ! wp_script_is( 'jquery-ui-datepicker', 'enqueued' ) ) { 1857 return; 1858 } 1859 1860 // Convert the PHP date format into jQuery UI's format. 1861 $datepicker_date_format = str_replace( 1862 array( 1863 'd', 1864 'j', 1865 'l', 1866 'z', // Day. 1867 'F', 1868 'M', 1869 'n', 1870 'm', // Month. 1871 'Y', 1872 'y', // Year. 1873 ), 1874 array( 1875 'dd', 1876 'd', 1877 'DD', 1878 'o', 1879 'MM', 1880 'M', 1881 'm', 1882 'mm', 1883 'yy', 1884 'y', 1885 ), 1886 get_option( 'date_format' ) 1887 ); 1888 1889 $datepicker_defaults = wp_json_encode( 1890 array( 1891 'closeText' => __( 'Close' ), 1892 'currentText' => __( 'Today' ), 1893 'monthNames' => array_values( $wp_locale->month ), 1894 'monthNamesShort' => array_values( $wp_locale->month_abbrev ), 1895 'nextText' => __( 'Next' ), 1896 'prevText' => __( 'Previous' ), 1897 'dayNames' => array_values( $wp_locale->weekday ), 1898 'dayNamesShort' => array_values( $wp_locale->weekday_abbrev ), 1899 'dayNamesMin' => array_values( $wp_locale->weekday_initial ), 1900 'dateFormat' => $datepicker_date_format, 1901 'firstDay' => absint( get_option( 'start_of_week' ) ), 1902 'isRTL' => $wp_locale->is_rtl(), 1903 ) 1904 ); 1905 1906 wp_add_inline_script( 'jquery-ui-datepicker', "jQuery(function(jQuery){jQuery.datepicker.setDefaults({$datepicker_defaults});});" ); 1907 } 1908 1909 /** 1910 * Localizes community events data that needs to be passed to dashboard.js. 1911 * 1912 * @since 4.8.0 1913 */ 1914 function wp_localize_community_events() { 1915 if ( ! wp_script_is( 'dashboard' ) ) { 1916 return; 1917 } 1918 1919 require_once ABSPATH . 'wp-admin/includes/class-wp-community-events.php'; 1920 1921 $user_id = get_current_user_id(); 1922 $saved_location = get_user_option( 'community-events-location', $user_id ); 1923 $saved_ip_address = isset( $saved_location['ip'] ) ? $saved_location['ip'] : false; 1924 $current_ip_address = WP_Community_Events::get_unsafe_client_ip(); 1925 1926 /* 1927 * If the user's location is based on their IP address, then update their 1928 * location when their IP address changes. This allows them to see events 1929 * in their current city when travelling. Otherwise, they would always be 1930 * shown events in the city where they were when they first loaded the 1931 * Dashboard, which could have been months or years ago. 1932 */ 1933 if ( $saved_ip_address && $current_ip_address && $current_ip_address !== $saved_ip_address ) { 1934 $saved_location['ip'] = $current_ip_address; 1935 update_user_meta( $user_id, 'community-events-location', $saved_location ); 1936 } 1937 1938 $events_client = new WP_Community_Events( $user_id, $saved_location ); 1939 1940 wp_localize_script( 1941 'dashboard', 1942 'communityEventsData', 1943 array( 1944 'nonce' => wp_create_nonce( 'community_events' ), 1945 'cache' => $events_client->get_cached_events(), 1946 'time_format' => get_option( 'time_format' ), 1947 ) 1948 ); 1949 } 1950 1951 /** 1952 * Administration Screen CSS for changing the styles. 1953 * 1954 * If installing the 'wp-admin/' directory will be replaced with './'. 1955 * 1956 * The $_wp_admin_css_colors global manages the Administration Screens CSS 1957 * stylesheet that is loaded. The option that is set is 'admin_color' and is the 1958 * color and key for the array. The value for the color key is an object with 1959 * a 'url' parameter that has the URL path to the CSS file. 1960 * 1961 * The query from $src parameter will be appended to the URL that is given from 1962 * the $_wp_admin_css_colors array value URL. 1963 * 1964 * @since 2.6.0 1965 * 1966 * @global array $_wp_admin_css_colors 1967 * 1968 * @param string $src Source URL. 1969 * @param string $handle Either 'colors' or 'colors-rtl'. 1970 * @return string|false URL path to CSS stylesheet for Administration Screens. 1971 */ 1972 function wp_style_loader_src( $src, $handle ) { 1973 global $_wp_admin_css_colors; 1974 1975 if ( wp_installing() ) { 1976 return preg_replace( '#^wp-admin/#', './', $src ); 1977 } 1978 1979 if ( 'colors' === $handle ) { 1980 $color = get_user_option( 'admin_color' ); 1981 1982 if ( empty( $color ) || ! isset( $_wp_admin_css_colors[ $color ] ) ) { 1983 $color = 'fresh'; 1984 } 1985 1986 $color = $_wp_admin_css_colors[ $color ]; 1987 $url = $color->url; 1988 1989 if ( ! $url ) { 1990 return false; 1991 } 1992 1993 $parsed = parse_url( $src ); 1994 if ( isset( $parsed['query'] ) && $parsed['query'] ) { 1995 wp_parse_str( $parsed['query'], $qv ); 1996 $url = add_query_arg( $qv, $url ); 1997 } 1998 1999 return $url; 2000 } 2001 2002 return $src; 2003 } 2004 2005 /** 2006 * Prints the script queue in the HTML head on admin pages. 2007 * 2008 * Postpones the scripts that were queued for the footer. 2009 * print_footer_scripts() is called in the footer to print these scripts. 2010 * 2011 * @since 2.8.0 2012 * 2013 * @see wp_print_scripts() 2014 * 2015 * @global bool $concatenate_scripts 2016 * 2017 * @return array 2018 */ 2019 function print_head_scripts() { 2020 global $concatenate_scripts; 2021 2022 if ( ! did_action( 'wp_print_scripts' ) ) { 2023 /** This action is documented in wp-includes/functions.wp-scripts.php */ 2024 do_action( 'wp_print_scripts' ); 2025 } 2026 2027 $wp_scripts = wp_scripts(); 2028 2029 script_concat_settings(); 2030 $wp_scripts->do_concat = $concatenate_scripts; 2031 $wp_scripts->do_head_items(); 2032 2033 /** 2034 * Filters whether to print the head scripts. 2035 * 2036 * @since 2.8.0 2037 * 2038 * @param bool $print Whether to print the head scripts. Default true. 2039 */ 2040 if ( apply_filters( 'print_head_scripts', true ) ) { 2041 _print_scripts(); 2042 } 2043 2044 $wp_scripts->reset(); 2045 return $wp_scripts->done; 2046 } 2047 2048 /** 2049 * Prints the scripts that were queued for the footer or too late for the HTML head. 2050 * 2051 * @since 2.8.0 2052 * 2053 * @global WP_Scripts $wp_scripts 2054 * @global bool $concatenate_scripts 2055 * 2056 * @return array 2057 */ 2058 function print_footer_scripts() { 2059 global $wp_scripts, $concatenate_scripts; 2060 2061 if ( ! ( $wp_scripts instanceof WP_Scripts ) ) { 2062 return array(); // No need to run if not instantiated. 2063 } 2064 script_concat_settings(); 2065 $wp_scripts->do_concat = $concatenate_scripts; 2066 $wp_scripts->do_footer_items(); 2067 2068 /** 2069 * Filters whether to print the footer scripts. 2070 * 2071 * @since 2.8.0 2072 * 2073 * @param bool $print Whether to print the footer scripts. Default true. 2074 */ 2075 if ( apply_filters( 'print_footer_scripts', true ) ) { 2076 _print_scripts(); 2077 } 2078 2079 $wp_scripts->reset(); 2080 return $wp_scripts->done; 2081 } 2082 2083 /** 2084 * Prints scripts (internal use only) 2085 * 2086 * @ignore 2087 * 2088 * @global WP_Scripts $wp_scripts 2089 * @global bool $compress_scripts 2090 */ 2091 function _print_scripts() { 2092 global $wp_scripts, $compress_scripts; 2093 2094 $zip = $compress_scripts ? 1 : 0; 2095 if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP ) { 2096 $zip = 'gzip'; 2097 } 2098 2099 $concat = trim( $wp_scripts->concat, ', ' ); 2100 $type_attr = current_theme_supports( 'html5', 'script' ) ? '' : " type='text/javascript'"; 2101 2102 if ( $concat ) { 2103 if ( ! empty( $wp_scripts->print_code ) ) { 2104 echo "\n<script{$type_attr}>\n"; 2105 echo "/* <![CDATA[ */\n"; // Not needed in HTML 5. 2106 echo $wp_scripts->print_code; 2107 echo "/* ]]> */\n"; 2108 echo "</script>\n"; 2109 } 2110 2111 $concat = str_split( $concat, 128 ); 2112 $concatenated = ''; 2113 2114 foreach ( $concat as $key => $chunk ) { 2115 $concatenated .= "&load%5Bchunk_{$key}%5D={$chunk}"; 2116 } 2117 2118 $src = $wp_scripts->base_url . "/wp-admin/load-scripts.php?c={$zip}" . $concatenated . '&ver=' . $wp_scripts->default_version; 2119 echo "<script{$type_attr} src='" . esc_attr( $src ) . "'></script>\n"; 2120 } 2121 2122 if ( ! empty( $wp_scripts->print_html ) ) { 2123 echo $wp_scripts->print_html; 2124 } 2125 } 2126 2127 /** 2128 * Prints the script queue in the HTML head on the front end. 2129 * 2130 * Postpones the scripts that were queued for the footer. 2131 * wp_print_footer_scripts() is called in the footer to print these scripts. 2132 * 2133 * @since 2.8.0 2134 * 2135 * @global WP_Scripts $wp_scripts 2136 * 2137 * @return array 2138 */ 2139 function wp_print_head_scripts() { 2140 global $wp_scripts; 2141 2142 if ( ! did_action( 'wp_print_scripts' ) ) { 2143 /** This action is documented in wp-includes/functions.wp-scripts.php */ 2144 do_action( 'wp_print_scripts' ); 2145 } 2146 2147 if ( ! ( $wp_scripts instanceof WP_Scripts ) ) { 2148 return array(); // No need to run if nothing is queued. 2149 } 2150 2151 return print_head_scripts(); 2152 } 2153 2154 /** 2155 * Private, for use in *_footer_scripts hooks 2156 * 2157 * @since 3.3.0 2158 */ 2159 function _wp_footer_scripts() { 2160 print_late_styles(); 2161 print_footer_scripts(); 2162 } 2163 2164 /** 2165 * Hooks to print the scripts and styles in the footer. 2166 * 2167 * @since 2.8.0 2168 */ 2169 function wp_print_footer_scripts() { 2170 /** 2171 * Fires when footer scripts are printed. 2172 * 2173 * @since 2.8.0 2174 */ 2175 do_action( 'wp_print_footer_scripts' ); 2176 } 2177 2178 /** 2179 * Wrapper for do_action( 'wp_enqueue_scripts' ). 2180 * 2181 * Allows plugins to queue scripts for the front end using wp_enqueue_script(). 2182 * Runs first in wp_head() where all is_home(), is_page(), etc. functions are available. 2183 * 2184 * @since 2.8.0 2185 */ 2186 function wp_enqueue_scripts() { 2187 /** 2188 * Fires when scripts and styles are enqueued. 2189 * 2190 * @since 2.8.0 2191 */ 2192 do_action( 'wp_enqueue_scripts' ); 2193 } 2194 2195 /** 2196 * Prints the styles queue in the HTML head on admin pages. 2197 * 2198 * @since 2.8.0 2199 * 2200 * @global bool $concatenate_scripts 2201 * 2202 * @return array 2203 */ 2204 function print_admin_styles() { 2205 global $concatenate_scripts; 2206 2207 $wp_styles = wp_styles(); 2208 2209 script_concat_settings(); 2210 $wp_styles->do_concat = $concatenate_scripts; 2211 $wp_styles->do_items( false ); 2212 2213 /** 2214 * Filters whether to print the admin styles. 2215 * 2216 * @since 2.8.0 2217 * 2218 * @param bool $print Whether to print the admin styles. Default true. 2219 */ 2220 if ( apply_filters( 'print_admin_styles', true ) ) { 2221 _print_styles(); 2222 } 2223 2224 $wp_styles->reset(); 2225 return $wp_styles->done; 2226 } 2227 2228 /** 2229 * Prints the styles that were queued too late for the HTML head. 2230 * 2231 * @since 3.3.0 2232 * 2233 * @global WP_Styles $wp_styles 2234 * @global bool $concatenate_scripts 2235 * 2236 * @return array|void 2237 */ 2238 function print_late_styles() { 2239 global $wp_styles, $concatenate_scripts; 2240 2241 if ( ! ( $wp_styles instanceof WP_Styles ) ) { 2242 return; 2243 } 2244 2245 script_concat_settings(); 2246 $wp_styles->do_concat = $concatenate_scripts; 2247 $wp_styles->do_footer_items(); 2248 2249 /** 2250 * Filters whether to print the styles queued too late for the HTML head. 2251 * 2252 * @since 3.3.0 2253 * 2254 * @param bool $print Whether to print the 'late' styles. Default true. 2255 */ 2256 if ( apply_filters( 'print_late_styles', true ) ) { 2257 _print_styles(); 2258 } 2259 2260 $wp_styles->reset(); 2261 return $wp_styles->done; 2262 } 2263 2264 /** 2265 * Prints styles (internal use only). 2266 * 2267 * @ignore 2268 * @since 3.3.0 2269 * 2270 * @global bool $compress_css 2271 */ 2272 function _print_styles() { 2273 global $compress_css; 2274 2275 $wp_styles = wp_styles(); 2276 2277 $zip = $compress_css ? 1 : 0; 2278 if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP ) { 2279 $zip = 'gzip'; 2280 } 2281 2282 $concat = trim( $wp_styles->concat, ', ' ); 2283 $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; 2284 2285 if ( $concat ) { 2286 $dir = $wp_styles->text_direction; 2287 $ver = $wp_styles->default_version; 2288 2289 $concat = str_split( $concat, 128 ); 2290 $concatenated = ''; 2291 2292 foreach ( $concat as $key => $chunk ) { 2293 $concatenated .= "&load%5Bchunk_{$key}%5D={$chunk}"; 2294 } 2295 2296 $href = $wp_styles->base_url . "/wp-admin/load-styles.php?c={$zip}&dir={$dir}" . $concatenated . '&ver=' . $ver; 2297 echo "<link rel='stylesheet' href='" . esc_attr( $href ) . "'{$type_attr} media='all' />\n"; 2298 2299 if ( ! empty( $wp_styles->print_code ) ) { 2300 echo "<style{$type_attr}>\n"; 2301 echo $wp_styles->print_code; 2302 echo "\n</style>\n"; 2303 } 2304 } 2305 2306 if ( ! empty( $wp_styles->print_html ) ) { 2307 echo $wp_styles->print_html; 2308 } 2309 } 2310 2311 /** 2312 * Determines the concatenation and compression settings for scripts and styles. 2313 * 2314 * @since 2.8.0 2315 * 2316 * @global bool $concatenate_scripts 2317 * @global bool $compress_scripts 2318 * @global bool $compress_css 2319 */ 2320 function script_concat_settings() { 2321 global $concatenate_scripts, $compress_scripts, $compress_css; 2322 2323 $compressed_output = ( ini_get( 'zlib.output_compression' ) || 'ob_gzhandler' === ini_get( 'output_handler' ) ); 2324 2325 $can_compress_scripts = ! wp_installing() && get_site_option( 'can_compress_scripts' ); 2326 2327 if ( ! isset( $concatenate_scripts ) ) { 2328 $concatenate_scripts = defined( 'CONCATENATE_SCRIPTS' ) ? CONCATENATE_SCRIPTS : true; 2329 if ( ( ! is_admin() && ! did_action( 'login_init' ) ) || ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ) { 2330 $concatenate_scripts = false; 2331 } 2332 } 2333 2334 if ( ! isset( $compress_scripts ) ) { 2335 $compress_scripts = defined( 'COMPRESS_SCRIPTS' ) ? COMPRESS_SCRIPTS : true; 2336 if ( $compress_scripts && ( ! $can_compress_scripts || $compressed_output ) ) { 2337 $compress_scripts = false; 2338 } 2339 } 2340 2341 if ( ! isset( $compress_css ) ) { 2342 $compress_css = defined( 'COMPRESS_CSS' ) ? COMPRESS_CSS : true; 2343 if ( $compress_css && ( ! $can_compress_scripts || $compressed_output ) ) { 2344 $compress_css = false; 2345 } 2346 } 2347 } 2348 2349 /** 2350 * Handles the enqueueing of block scripts and styles that are common to both 2351 * the editor and the front-end. 2352 * 2353 * @since 5.0.0 2354 */ 2355 function wp_common_block_scripts_and_styles() { 2356 if ( is_admin() && ! wp_should_load_block_editor_scripts_and_styles() ) { 2357 return; 2358 } 2359 2360 wp_enqueue_style( 'wp-block-library' ); 2361 2362 if ( current_theme_supports( 'wp-block-styles' ) ) { 2363 if ( wp_should_load_separate_core_block_assets() ) { 2364 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'css' : 'min.css'; 2365 $files = glob( __DIR__ . "/blocks/**/theme.$suffix" ); 2366 foreach ( $files as $path ) { 2367 $block_name = basename( dirname( $path ) ); 2368 if ( is_rtl() && file_exists( __DIR__ . "/blocks/$block_name/theme-rtl.$suffix" ) ) { 2369 $path = __DIR__ . "/blocks/$block_name/theme-rtl.$suffix"; 2370 } 2371 wp_add_inline_style( "wp-block-{$block_name}", file_get_contents( $path ) ); 2372 } 2373 } else { 2374 wp_enqueue_style( 'wp-block-library-theme' ); 2375 } 2376 } 2377 2378 /** 2379 * Fires after enqueuing block assets for both editor and front-end. 2380 * 2381 * Call `add_action` on any hook before 'wp_enqueue_scripts'. 2382 * 2383 * In the function call you supply, simply use `wp_enqueue_script` and 2384 * `wp_enqueue_style` to add your functionality to the Gutenberg editor. 2385 * 2386 * @since 5.0.0 2387 */ 2388 do_action( 'enqueue_block_assets' ); 2389 } 2390 2391 /** 2392 * Applies a filter to the list of style nodes that comes from WP_Theme_JSON::get_style_nodes(). 2393 * 2394 * This particular filter removes all of the blocks from the array. 2395 * 2396 * We want WP_Theme_JSON to be ignorant of the implementation details of how the CSS is being used. 2397 * This filter allows us to modify the output of WP_Theme_JSON depending on whether or not we are 2398 * loading separate assets, without making the class aware of that detail. 2399 * 2400 * @since 6.1.0 2401 * 2402 * @param array $nodes The nodes to filter. 2403 * @return array A filtered array of style nodes. 2404 */ 2405 function wp_filter_out_block_nodes( $nodes ) { 2406 return array_filter( 2407 $nodes, 2408 static function( $node ) { 2409 return ! in_array( 'blocks', $node['path'], true ); 2410 }, 2411 ARRAY_FILTER_USE_BOTH 2412 ); 2413 } 2414 2415 /** 2416 * Enqueues the global styles defined via theme.json. 2417 * 2418 * @since 5.8.0 2419 */ 2420 function wp_enqueue_global_styles() { 2421 $separate_assets = wp_should_load_separate_core_block_assets(); 2422 $is_block_theme = wp_is_block_theme(); 2423 $is_classic_theme = ! $is_block_theme; 2424 2425 /* 2426 * Global styles should be printed in the head when loading all styles combined. 2427 * The footer should only be used to print global styles for classic themes with separate core assets enabled. 2428 * 2429 * See https://core.trac.wordpress.org/ticket/53494. 2430 */ 2431 if ( 2432 ( $is_block_theme && doing_action( 'wp_footer' ) ) || 2433 ( $is_classic_theme && doing_action( 'wp_footer' ) && ! $separate_assets ) || 2434 ( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) && $separate_assets ) 2435 ) { 2436 return; 2437 } 2438 2439 /* 2440 * If loading the CSS for each block separately, then load the theme.json CSS conditionally. 2441 * This removes the CSS from the global-styles stylesheet and adds it to the inline CSS for each block. 2442 * This filter must be registered before calling wp_get_global_stylesheet(); 2443 */ 2444 add_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); 2445 2446 $stylesheet = wp_get_global_stylesheet(); 2447 2448 if ( empty( $stylesheet ) ) { 2449 return; 2450 } 2451 2452 wp_register_style( 'global-styles', false ); 2453 wp_add_inline_style( 'global-styles', $stylesheet ); 2454 wp_enqueue_style( 'global-styles' ); 2455 2456 // Add each block as an inline css. 2457 wp_add_global_styles_for_blocks(); 2458 } 2459 2460 /** 2461 * Enqueues the global styles custom css defined via theme.json. 2462 * 2463 * @since 6.2.0 2464 */ 2465 function wp_enqueue_global_styles_custom_css() { 2466 if ( ! wp_is_block_theme() ) { 2467 return; 2468 } 2469 2470 // Don't enqueue Customizer's custom CSS separately. 2471 remove_action( 'wp_head', 'wp_custom_css_cb', 101 ); 2472 2473 $custom_css = wp_get_custom_css(); 2474 $custom_css .= wp_get_global_styles_custom_css(); 2475 2476 if ( ! empty( $custom_css ) ) { 2477 wp_add_inline_style( 'global-styles', $custom_css ); 2478 } 2479 } 2480 2481 /** 2482 * Renders the SVG filters supplied by theme.json. 2483 * 2484 * Note that this doesn't render the per-block user-defined 2485 * filters which are handled by wp_render_duotone_support, 2486 * but it should be rendered before the filtered content 2487 * in the body to satisfy Safari's rendering quirks. 2488 * 2489 * @since 5.9.1 2490 */ 2491 function wp_global_styles_render_svg_filters() { 2492 /* 2493 * When calling via the in_admin_header action, we only want to render the 2494 * SVGs on block editor pages. 2495 */ 2496 if ( 2497 is_admin() && 2498 ! get_current_screen()->is_block_editor() 2499 ) { 2500 return; 2501 } 2502 2503 $filters = wp_get_global_styles_svg_filters(); 2504 if ( ! empty( $filters ) ) { 2505 echo $filters; 2506 } 2507 } 2508 2509 /** 2510 * Checks if the editor scripts and styles for all registered block types 2511 * should be enqueued on the current screen. 2512 * 2513 * @since 5.6.0 2514 * 2515 * @global WP_Screen $current_screen WordPress current screen object. 2516 * 2517 * @return bool Whether scripts and styles should be enqueued. 2518 */ 2519 function wp_should_load_block_editor_scripts_and_styles() { 2520 global $current_screen; 2521 2522 $is_block_editor_screen = ( $current_screen instanceof WP_Screen ) && $current_screen->is_block_editor(); 2523 2524 /** 2525 * Filters the flag that decides whether or not block editor scripts and styles 2526 * are going to be enqueued on the current screen. 2527 * 2528 * @since 5.6.0 2529 * 2530 * @param bool $is_block_editor_screen Current value of the flag. 2531 */ 2532 return apply_filters( 'should_load_block_editor_scripts_and_styles', $is_block_editor_screen ); 2533 } 2534 2535 /** 2536 * Checks whether separate styles should be loaded for core blocks on-render. 2537 * 2538 * When this function returns true, other functions ensure that core blocks 2539 * only load their assets on-render, and each block loads its own, individual 2540 * assets. Third-party blocks only load their assets when rendered. 2541 * 2542 * When this function returns false, all core block assets are loaded regardless 2543 * of whether they are rendered in a page or not, because they are all part of 2544 * the `block-library/style.css` file. Assets for third-party blocks are always 2545 * enqueued regardless of whether they are rendered or not. 2546 * 2547 * This only affects front end and not the block editor screens. 2548 * 2549 * @see wp_enqueue_registered_block_scripts_and_styles() 2550 * @see register_block_style_handle() 2551 * 2552 * @since 5.8.0 2553 * 2554 * @return bool Whether separate assets will be loaded. 2555 */ 2556 function wp_should_load_separate_core_block_assets() { 2557 if ( is_admin() || is_feed() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { 2558 return false; 2559 } 2560 2561 /** 2562 * Filters whether block styles should be loaded separately. 2563 * 2564 * Returning false loads all core block assets, regardless of whether they are rendered 2565 * in a page or not. Returning true loads core block assets only when they are rendered. 2566 * 2567 * @since 5.8.0 2568 * 2569 * @param bool $load_separate_assets Whether separate assets will be loaded. 2570 * Default false (all block assets are loaded, even when not used). 2571 */ 2572 return apply_filters( 'should_load_separate_core_block_assets', false ); 2573 } 2574 2575 /** 2576 * Enqueues registered block scripts and styles, depending on current rendered 2577 * context (only enqueuing editor scripts while in context of the editor). 2578 * 2579 * @since 5.0.0 2580 * 2581 * @global WP_Screen $current_screen WordPress current screen object. 2582 */ 2583 function wp_enqueue_registered_block_scripts_and_styles() { 2584 global $current_screen; 2585 2586 if ( wp_should_load_separate_core_block_assets() ) { 2587 return; 2588 } 2589 2590 $load_editor_scripts_and_styles = is_admin() && wp_should_load_block_editor_scripts_and_styles(); 2591 2592 $block_registry = WP_Block_Type_Registry::get_instance(); 2593 foreach ( $block_registry->get_all_registered() as $block_name => $block_type ) { 2594 // Front-end and editor styles. 2595 foreach ( $block_type->style_handles as $style_handle ) { 2596 wp_enqueue_style( $style_handle ); 2597 } 2598 2599 // Front-end and editor scripts. 2600 foreach ( $block_type->script_handles as $script_handle ) { 2601 wp_enqueue_script( $script_handle ); 2602 } 2603 2604 if ( $load_editor_scripts_and_styles ) { 2605 // Editor styles. 2606 foreach ( $block_type->editor_style_handles as $editor_style_handle ) { 2607 wp_enqueue_style( $editor_style_handle ); 2608 } 2609 2610 // Editor scripts. 2611 foreach ( $block_type->editor_script_handles as $editor_script_handle ) { 2612 wp_enqueue_script( $editor_script_handle ); 2613 } 2614 } 2615 } 2616 } 2617 2618 /** 2619 * Function responsible for enqueuing the styles required for block styles functionality on the editor and on the frontend. 2620 * 2621 * @since 5.3.0 2622 * 2623 * @global WP_Styles $wp_styles 2624 */ 2625 function enqueue_block_styles_assets() { 2626 global $wp_styles; 2627 2628 $block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered(); 2629 2630 foreach ( $block_styles as $block_name => $styles ) { 2631 foreach ( $styles as $style_properties ) { 2632 if ( isset( $style_properties['style_handle'] ) ) { 2633 2634 // If the site loads separate styles per-block, enqueue the stylesheet on render. 2635 if ( wp_should_load_separate_core_block_assets() ) { 2636 add_filter( 2637 'render_block', 2638 static function( $html, $block ) use ( $block_name, $style_properties ) { 2639 if ( $block['blockName'] === $block_name ) { 2640 wp_enqueue_style( $style_properties['style_handle'] ); 2641 } 2642 return $html; 2643 }, 2644 10, 2645 2 2646 ); 2647 } else { 2648 wp_enqueue_style( $style_properties['style_handle'] ); 2649 } 2650 } 2651 if ( isset( $style_properties['inline_style'] ) ) { 2652 2653 // Default to "wp-block-library". 2654 $handle = 'wp-block-library'; 2655 2656 // If the site loads separate styles per-block, check if the block has a stylesheet registered. 2657 if ( wp_should_load_separate_core_block_assets() ) { 2658 $block_stylesheet_handle = generate_block_asset_handle( $block_name, 'style' ); 2659 2660 if ( isset( $wp_styles->registered[ $block_stylesheet_handle ] ) ) { 2661 $handle = $block_stylesheet_handle; 2662 } 2663 } 2664 2665 // Add inline styles to the calculated handle. 2666 wp_add_inline_style( $handle, $style_properties['inline_style'] ); 2667 } 2668 } 2669 } 2670 } 2671 2672 /** 2673 * Function responsible for enqueuing the assets required for block styles functionality on the editor. 2674 * 2675 * @since 5.3.0 2676 */ 2677 function enqueue_editor_block_styles_assets() { 2678 $block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered(); 2679 2680 $register_script_lines = array( '( function() {' ); 2681 foreach ( $block_styles as $block_name => $styles ) { 2682 foreach ( $styles as $style_properties ) { 2683 $block_style = array( 2684 'name' => $style_properties['name'], 2685 'label' => $style_properties['label'], 2686 ); 2687 if ( isset( $style_properties['is_default'] ) ) { 2688 $block_style['isDefault'] = $style_properties['is_default']; 2689 } 2690 $register_script_lines[] = sprintf( 2691 ' wp.blocks.registerBlockStyle( \'%s\', %s );', 2692 $block_name, 2693 wp_json_encode( $block_style ) 2694 ); 2695 } 2696 } 2697 $register_script_lines[] = '} )();'; 2698 $inline_script = implode( "\n", $register_script_lines ); 2699 2700 wp_register_script( 'wp-block-styles', false, array( 'wp-blocks' ), true, true ); 2701 wp_add_inline_script( 'wp-block-styles', $inline_script ); 2702 wp_enqueue_script( 'wp-block-styles' ); 2703 } 2704 2705 /** 2706 * Enqueues the assets required for the block directory within the block editor. 2707 * 2708 * @since 5.5.0 2709 */ 2710 function wp_enqueue_editor_block_directory_assets() { 2711 wp_enqueue_script( 'wp-block-directory' ); 2712 wp_enqueue_style( 'wp-block-directory' ); 2713 } 2714 2715 /** 2716 * Enqueues the assets required for the format library within the block editor. 2717 * 2718 * @since 5.8.0 2719 */ 2720 function wp_enqueue_editor_format_library_assets() { 2721 wp_enqueue_script( 'wp-format-library' ); 2722 wp_enqueue_style( 'wp-format-library' ); 2723 } 2724 2725 /** 2726 * Sanitizes an attributes array into an attributes string to be placed inside a `<script>` tag. 2727 * 2728 * Automatically injects type attribute if needed. 2729 * Used by {@see wp_get_script_tag()} and {@see wp_get_inline_script_tag()}. 2730 * 2731 * @since 5.7.0 2732 * 2733 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 2734 * @return string String made of sanitized `<script>` tag attributes. 2735 */ 2736 function wp_sanitize_script_attributes( $attributes ) { 2737 $html5_script_support = ! is_admin() && ! current_theme_supports( 'html5', 'script' ); 2738 $attributes_string = ''; 2739 2740 // If HTML5 script tag is supported, only the attribute name is added 2741 // to $attributes_string for entries with a boolean value, and that are true. 2742 foreach ( $attributes as $attribute_name => $attribute_value ) { 2743 if ( is_bool( $attribute_value ) ) { 2744 if ( $attribute_value ) { 2745 $attributes_string .= $html5_script_support ? sprintf( ' %1$s="%2$s"', esc_attr( $attribute_name ), esc_attr( $attribute_name ) ) : ' ' . esc_attr( $attribute_name ); 2746 } 2747 } else { 2748 $attributes_string .= sprintf( ' %1$s="%2$s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) ); 2749 } 2750 } 2751 2752 return $attributes_string; 2753 } 2754 2755 /** 2756 * Formats `<script>` loader tags. 2757 * 2758 * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. 2759 * Automatically injects type attribute if needed. 2760 * 2761 * @since 5.7.0 2762 * 2763 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 2764 * @return string String containing `<script>` opening and closing tags. 2765 */ 2766 function wp_get_script_tag( $attributes ) { 2767 if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) { 2768 $attributes['type'] = 'text/javascript'; 2769 } 2770 /** 2771 * Filters attributes to be added to a script tag. 2772 * 2773 * @since 5.7.0 2774 * 2775 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 2776 * Only the attribute name is added to the `<script>` tag for 2777 * entries with a boolean value, and that are true. 2778 */ 2779 $attributes = apply_filters( 'wp_script_attributes', $attributes ); 2780 2781 return sprintf( "<script%s></script>\n", wp_sanitize_script_attributes( $attributes ) ); 2782 } 2783 2784 /** 2785 * Prints formatted `<script>` loader tag. 2786 * 2787 * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. 2788 * Automatically injects type attribute if needed. 2789 * 2790 * @since 5.7.0 2791 * 2792 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 2793 */ 2794 function wp_print_script_tag( $attributes ) { 2795 echo wp_get_script_tag( $attributes ); 2796 } 2797 2798 /** 2799 * Wraps inline JavaScript in `<script>` tag. 2800 * 2801 * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. 2802 * Automatically injects type attribute if needed. 2803 * 2804 * @since 5.7.0 2805 * 2806 * @param string $javascript Inline JavaScript code. 2807 * @param array $attributes Optional. Key-value pairs representing `<script>` tag attributes. 2808 * @return string String containing inline JavaScript code wrapped around `<script>` tag. 2809 */ 2810 function wp_get_inline_script_tag( $javascript, $attributes = array() ) { 2811 if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) { 2812 $attributes['type'] = 'text/javascript'; 2813 } 2814 /** 2815 * Filters attributes to be added to a script tag. 2816 * 2817 * @since 5.7.0 2818 * 2819 * @param array $attributes Key-value pairs representing `<script>` tag attributes. 2820 * Only the attribute name is added to the `<script>` tag for 2821 * entries with a boolean value, and that are true. 2822 * @param string $javascript Inline JavaScript code. 2823 */ 2824 $attributes = apply_filters( 'wp_inline_script_attributes', $attributes, $javascript ); 2825 2826 $javascript = "\n" . trim( $javascript, "\n\r " ) . "\n"; 2827 2828 return sprintf( "<script%s>%s</script>\n", wp_sanitize_script_attributes( $attributes ), $javascript ); 2829 } 2830 2831 /** 2832 * Prints inline JavaScript wrapped in `<script>` tag. 2833 * 2834 * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. 2835 * Automatically injects type attribute if needed. 2836 * 2837 * @since 5.7.0 2838 * 2839 * @param string $javascript Inline JavaScript code. 2840 * @param array $attributes Optional. Key-value pairs representing `<script>` tag attributes. 2841 */ 2842 function wp_print_inline_script_tag( $javascript, $attributes = array() ) { 2843 echo wp_get_inline_script_tag( $javascript, $attributes ); 2844 } 2845 2846 /** 2847 * Allows small styles to be inlined. 2848 * 2849 * This improves performance and sustainability, and is opt-in. Stylesheets can opt in 2850 * by adding `path` data using `wp_style_add_data`, and defining the file's absolute path: 2851 * 2852 * wp_style_add_data( $style_handle, 'path', $file_path ); 2853 * 2854 * @since 5.8.0 2855 * 2856 * @global WP_Styles $wp_styles 2857 */ 2858 function wp_maybe_inline_styles() { 2859 global $wp_styles; 2860 2861 $total_inline_limit = 20000; 2862 /** 2863 * The maximum size of inlined styles in bytes. 2864 * 2865 * @since 5.8.0 2866 * 2867 * @param int $total_inline_limit The file-size threshold, in bytes. Default 20000. 2868 */ 2869 $total_inline_limit = apply_filters( 'styles_inline_size_limit', $total_inline_limit ); 2870 2871 $styles = array(); 2872 2873 // Build an array of styles that have a path defined. 2874 foreach ( $wp_styles->queue as $handle ) { 2875 if ( wp_styles()->get_data( $handle, 'path' ) && file_exists( $wp_styles->registered[ $handle ]->extra['path'] ) ) { 2876 $styles[] = array( 2877 'handle' => $handle, 2878 'src' => $wp_styles->registered[ $handle ]->src, 2879 'path' => $wp_styles->registered[ $handle ]->extra['path'], 2880 'size' => filesize( $wp_styles->registered[ $handle ]->extra['path'] ), 2881 ); 2882 } 2883 } 2884 2885 if ( ! empty( $styles ) ) { 2886 // Reorder styles array based on size. 2887 usort( 2888 $styles, 2889 static function( $a, $b ) { 2890 return ( $a['size'] <= $b['size'] ) ? -1 : 1; 2891 } 2892 ); 2893 2894 /* 2895 * The total inlined size. 2896 * 2897 * On each iteration of the loop, if a style gets added inline the value of this var increases 2898 * to reflect the total size of inlined styles. 2899 */ 2900 $total_inline_size = 0; 2901 2902 // Loop styles. 2903 foreach ( $styles as $style ) { 2904 2905 // Size check. Since styles are ordered by size, we can break the loop. 2906 if ( $total_inline_size + $style['size'] > $total_inline_limit ) { 2907 break; 2908 } 2909 2910 // Get the styles if we don't already have them. 2911 $style['css'] = file_get_contents( $style['path'] ); 2912 2913 // Check if the style contains relative URLs that need to be modified. 2914 // URLs relative to the stylesheet's path should be converted to relative to the site's root. 2915 $style['css'] = _wp_normalize_relative_css_links( $style['css'], $style['src'] ); 2916 2917 // Set `src` to `false` and add styles inline. 2918 $wp_styles->registered[ $style['handle'] ]->src = false; 2919 if ( empty( $wp_styles->registered[ $style['handle'] ]->extra['after'] ) ) { 2920 $wp_styles->registered[ $style['handle'] ]->extra['after'] = array(); 2921 } 2922 array_unshift( $wp_styles->registered[ $style['handle'] ]->extra['after'], $style['css'] ); 2923 2924 // Add the styles size to the $total_inline_size var. 2925 $total_inline_size += (int) $style['size']; 2926 } 2927 } 2928 } 2929 2930 /** 2931 * Makes URLs relative to the WordPress installation. 2932 * 2933 * @since 5.9.0 2934 * @access private 2935 * 2936 * @param string $css The CSS to make URLs relative to the WordPress installation. 2937 * @param string $stylesheet_url The URL to the stylesheet. 2938 * 2939 * @return string The CSS with URLs made relative to the WordPress installation. 2940 */ 2941 function _wp_normalize_relative_css_links( $css, $stylesheet_url ) { 2942 return preg_replace_callback( 2943 '#(url\s*\(\s*[\'"]?\s*)([^\'"\)]+)#', 2944 static function ( $matches ) use ( $stylesheet_url ) { 2945 list( , $prefix, $url ) = $matches; 2946 2947 // Short-circuit if the URL does not require normalization. 2948 if ( 2949 str_starts_with( $url, 'http:' ) || 2950 str_starts_with( $url, 'https:' ) || 2951 str_starts_with( $url, '//' ) || 2952 str_starts_with( $url, '#' ) || 2953 str_starts_with( $url, 'data:' ) 2954 ) { 2955 return $matches[0]; 2956 } 2957 2958 // Build the absolute URL. 2959 $absolute_url = dirname( $stylesheet_url ) . '/' . $url; 2960 $absolute_url = str_replace( '/./', '/', $absolute_url ); 2961 2962 // Convert to URL related to the site root. 2963 $url = wp_make_link_relative( $absolute_url ); 2964 2965 return $prefix . $url; 2966 }, 2967 $css 2968 ); 2969 } 2970 2971 /** 2972 * Function that enqueues the CSS Custom Properties coming from theme.json. 2973 * 2974 * @since 5.9.0 2975 */ 2976 function wp_enqueue_global_styles_css_custom_properties() { 2977 wp_register_style( 'global-styles-css-custom-properties', false ); 2978 wp_add_inline_style( 'global-styles-css-custom-properties', wp_get_global_stylesheet( array( 'variables' ) ) ); 2979 wp_enqueue_style( 'global-styles-css-custom-properties' ); 2980 } 2981 2982 /** 2983 * Hooks inline styles in the proper place, depending on the active theme. 2984 * 2985 * @since 5.9.1 2986 * @since 6.1.0 Added the `$priority` parameter. 2987 * 2988 * For block themes, styles are loaded in the head. 2989 * For classic ones, styles are loaded in the body because the wp_head action happens before render_block. 2990 * 2991 * @link https://core.trac.wordpress.org/ticket/53494. 2992 * 2993 * @param string $style String containing the CSS styles to be added. 2994 * @param int $priority To set the priority for the add_action. 2995 */ 2996 function wp_enqueue_block_support_styles( $style, $priority = 10 ) { 2997 $action_hook_name = 'wp_footer'; 2998 if ( wp_is_block_theme() ) { 2999 $action_hook_name = 'wp_head'; 3000 } 3001 add_action( 3002 $action_hook_name, 3003 static function () use ( $style ) { 3004 echo "<style>$style</style>\n"; 3005 }, 3006 $priority 3007 ); 3008 } 3009 3010 /** 3011 * Fetches, processes and compiles stored core styles, then combines and renders them to the page. 3012 * Styles are stored via the style engine API. 3013 * 3014 * @link https://developer.wordpress.org/block-editor/reference-guides/packages/packages-style-engine/ 3015 * 3016 * @since 6.1.0 3017 * 3018 * @param array $options { 3019 * Optional. An array of options to pass to wp_style_engine_get_stylesheet_from_context(). 3020 * Default empty array. 3021 * 3022 * @type bool $optimize Whether to optimize the CSS output, e.g., combine rules. 3023 * Default true. 3024 * @type bool $prettify Whether to add new lines and indents to output. 3025 * Default to whether the `SCRIPT_DEBUG` constant is defined. 3026 * } 3027 */ 3028 function wp_enqueue_stored_styles( $options = array() ) { 3029 $is_block_theme = wp_is_block_theme(); 3030 $is_classic_theme = ! $is_block_theme; 3031 3032 /* 3033 * For block themes, this function prints stored styles in the header. 3034 * For classic themes, in the footer. 3035 */ 3036 if ( 3037 ( $is_block_theme && doing_action( 'wp_footer' ) ) || 3038 ( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) ) 3039 ) { 3040 return; 3041 } 3042 3043 $core_styles_keys = array( 'block-supports' ); 3044 $compiled_core_stylesheet = ''; 3045 $style_tag_id = 'core'; 3046 // Adds comment if code is prettified to identify core styles sections in debugging. 3047 $should_prettify = isset( $options['prettify'] ) ? true === $options['prettify'] : defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG; 3048 foreach ( $core_styles_keys as $style_key ) { 3049 if ( $should_prettify ) { 3050 $compiled_core_stylesheet .= "/**\n * Core styles: $style_key\n */\n"; 3051 } 3052 // Chains core store ids to signify what the styles contain. 3053 $style_tag_id .= '-' . $style_key; 3054 $compiled_core_stylesheet .= wp_style_engine_get_stylesheet_from_context( $style_key, $options ); 3055 } 3056 3057 // Combines Core styles. 3058 if ( ! empty( $compiled_core_stylesheet ) ) { 3059 wp_register_style( $style_tag_id, false ); 3060 wp_add_inline_style( $style_tag_id, $compiled_core_stylesheet ); 3061 wp_enqueue_style( $style_tag_id ); 3062 } 3063 3064 // Prints out any other stores registered by themes or otherwise. 3065 $additional_stores = WP_Style_Engine_CSS_Rules_Store::get_stores(); 3066 foreach ( array_keys( $additional_stores ) as $store_name ) { 3067 if ( in_array( $store_name, $core_styles_keys, true ) ) { 3068 continue; 3069 } 3070 $styles = wp_style_engine_get_stylesheet_from_context( $store_name, $options ); 3071 if ( ! empty( $styles ) ) { 3072 $key = "wp-style-engine-$store_name"; 3073 wp_register_style( $key, false ); 3074 wp_add_inline_style( $key, $styles ); 3075 wp_enqueue_style( $key ); 3076 } 3077 } 3078 } 3079 3080 /** 3081 * Enqueues a stylesheet for a specific block. 3082 * 3083 * If the theme has opted-in to separate-styles loading, 3084 * then the stylesheet will be enqueued on-render, 3085 * otherwise when the block inits. 3086 * 3087 * @since 5.9.0 3088 * 3089 * @param string $block_name The block-name, including namespace. 3090 * @param array $args { 3091 * An array of arguments. See wp_register_style() for full information about each argument. 3092 * 3093 * @type string $handle The handle for the stylesheet. 3094 * @type string|false $src The source URL of the stylesheet. 3095 * @type string[] $deps Array of registered stylesheet handles this stylesheet depends on. 3096 * @type string|bool|null $ver Stylesheet version number. 3097 * @type string $media The media for which this stylesheet has been defined. 3098 * } 3099 */ 3100 function wp_enqueue_block_style( $block_name, $args ) { 3101 $args = wp_parse_args( 3102 $args, 3103 array( 3104 'handle' => '', 3105 'src' => '', 3106 'deps' => array(), 3107 'ver' => false, 3108 'media' => 'all', 3109 ) 3110 ); 3111 3112 /** 3113 * Callback function to register and enqueue styles. 3114 * 3115 * @param string $content When the callback is used for the render_block filter, 3116 * the content needs to be returned so the function parameter 3117 * is to ensure the content exists. 3118 * @return string Block content. 3119 */ 3120 $callback = static function( $content ) use ( $args ) { 3121 // Register the stylesheet. 3122 if ( ! empty( $args['src'] ) ) { 3123 wp_register_style( $args['handle'], $args['src'], $args['deps'], $args['ver'], $args['media'] ); 3124 } 3125 3126 // Add `path` data if provided. 3127 if ( isset( $args['path'] ) ) { 3128 wp_style_add_data( $args['handle'], 'path', $args['path'] ); 3129 3130 // Get the RTL file path. 3131 $rtl_file_path = str_replace( '.css', '-rtl.css', $args['path'] ); 3132 3133 // Add RTL stylesheet. 3134 if ( file_exists( $rtl_file_path ) ) { 3135 wp_style_add_data( $args['handle'], 'rtl', 'replace' ); 3136 3137 if ( is_rtl() ) { 3138 wp_style_add_data( $args['handle'], 'path', $rtl_file_path ); 3139 } 3140 } 3141 } 3142 3143 // Enqueue the stylesheet. 3144 wp_enqueue_style( $args['handle'] ); 3145 3146 return $content; 3147 }; 3148 3149 $hook = did_action( 'wp_enqueue_scripts' ) ? 'wp_footer' : 'wp_enqueue_scripts'; 3150 if ( wp_should_load_separate_core_block_assets() ) { 3151 /** 3152 * Callback function to register and enqueue styles. 3153 * 3154 * @param string $content The block content. 3155 * @param array $block The full block, including name and attributes. 3156 * @return string Block content. 3157 */ 3158 $callback_separate = static function( $content, $block ) use ( $block_name, $callback ) { 3159 if ( ! empty( $block['blockName'] ) && $block_name === $block['blockName'] ) { 3160 return $callback( $content ); 3161 } 3162 return $content; 3163 }; 3164 3165 /* 3166 * The filter's callback here is an anonymous function because 3167 * using a named function in this case is not possible. 3168 * 3169 * The function cannot be unhooked, however, users are still able 3170 * to dequeue the stylesheets registered/enqueued by the callback 3171 * which is why in this case, using an anonymous function 3172 * was deemed acceptable. 3173 */ 3174 add_filter( 'render_block', $callback_separate, 10, 2 ); 3175 return; 3176 } 3177 3178 /* 3179 * The filter's callback here is an anonymous function because 3180 * using a named function in this case is not possible. 3181 * 3182 * The function cannot be unhooked, however, users are still able 3183 * to dequeue the stylesheets registered/enqueued by the callback 3184 * which is why in this case, using an anonymous function 3185 * was deemed acceptable. 3186 */ 3187 add_filter( $hook, $callback ); 3188 3189 // Enqueue assets in the editor. 3190 add_action( 'enqueue_block_assets', $callback ); 3191 } 3192 3193 /** 3194 * Runs the theme.json webfonts handler. 3195 * 3196 * Using `WP_Theme_JSON_Resolver`, it gets the fonts defined 3197 * in the `theme.json` for the current selection and style 3198 * variations, validates the font-face properties, generates 3199 * the '@font-face' style declarations, and then enqueues the 3200 * styles for both the editor and front-end. 3201 * 3202 * Design Notes: 3203 * This is not a public API, but rather an internal handler. 3204 * A future public Webfonts API will replace this stopgap code. 3205 * 3206 * This code design is intentional. 3207 * a. It hides the inner-workings. 3208 * b. It does not expose API ins or outs for consumption. 3209 * c. It only works with a theme's `theme.json`. 3210 * 3211 * Why? 3212 * a. To avoid backwards-compatibility issues when 3213 * the Webfonts API is introduced in Core. 3214 * b. To make `fontFace` declarations in `theme.json` work. 3215 * 3216 * @link https://github.com/WordPress/gutenberg/issues/40472 3217 * 3218 * @since 6.0.0 3219 * @access private 3220 */ 3221 function _wp_theme_json_webfonts_handler() { 3222 // Block themes are unavailable during installation. 3223 if ( wp_installing() ) { 3224 return; 3225 } 3226 3227 if ( ! wp_theme_has_theme_json() ) { 3228 return; 3229 } 3230 3231 // Webfonts to be processed. 3232 $registered_webfonts = array(); 3233 3234 /** 3235 * Gets the webfonts from theme.json. 3236 * 3237 * @since 6.0.0 3238 * 3239 * @return array Array of defined webfonts. 3240 */ 3241 $fn_get_webfonts_from_theme_json = static function() { 3242 // Get settings from theme.json. 3243 $settings = WP_Theme_JSON_Resolver::get_merged_data()->get_settings(); 3244 3245 // If in the editor, add webfonts defined in variations. 3246 if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { 3247 $variations = WP_Theme_JSON_Resolver::get_style_variations(); 3248 foreach ( $variations as $variation ) { 3249 // Skip if fontFamilies are not defined in the variation. 3250 if ( empty( $variation['settings']['typography']['fontFamilies'] ) ) { 3251 continue; 3252 } 3253 3254 // Initialize the array structure. 3255 if ( empty( $settings['typography'] ) ) { 3256 $settings['typography'] = array(); 3257 } 3258 if ( empty( $settings['typography']['fontFamilies'] ) ) { 3259 $settings['typography']['fontFamilies'] = array(); 3260 } 3261 if ( empty( $settings['typography']['fontFamilies']['theme'] ) ) { 3262 $settings['typography']['fontFamilies']['theme'] = array(); 3263 } 3264 3265 // Combine variations with settings. Remove duplicates. 3266 $settings['typography']['fontFamilies']['theme'] = array_merge( $settings['typography']['fontFamilies']['theme'], $variation['settings']['typography']['fontFamilies']['theme'] ); 3267 $settings['typography']['fontFamilies'] = array_unique( $settings['typography']['fontFamilies'] ); 3268 } 3269 } 3270 3271 // Bail out early if there are no settings for webfonts. 3272 if ( empty( $settings['typography']['fontFamilies'] ) ) { 3273 return array(); 3274 } 3275 3276 $webfonts = array(); 3277 3278 // Look for fontFamilies. 3279 foreach ( $settings['typography']['fontFamilies'] as $font_families ) { 3280 foreach ( $font_families as $font_family ) { 3281 3282 // Skip if fontFace is not defined. 3283 if ( empty( $font_family['fontFace'] ) ) { 3284 continue; 3285 } 3286 3287 // Skip if fontFace is not an array of webfonts. 3288 if ( ! is_array( $font_family['fontFace'] ) ) { 3289 continue; 3290 } 3291 3292 $webfonts = array_merge( $webfonts, $font_family['fontFace'] ); 3293 } 3294 } 3295 3296 return $webfonts; 3297 }; 3298 3299 /** 3300 * Transforms each 'src' into an URI by replacing 'file:./' 3301 * placeholder from theme.json. 3302 * 3303 * The absolute path to the webfont file(s) cannot be defined in 3304 * theme.json. `file:./` is the placeholder which is replaced by 3305 * the theme's URL path to the theme's root. 3306 * 3307 * @since 6.0.0 3308 * 3309 * @param array $src Webfont file(s) `src`. 3310 * @return array Webfont's `src` in URI. 3311 */ 3312 $fn_transform_src_into_uri = static function( array $src ) { 3313 foreach ( $src as $key => $url ) { 3314 // Tweak the URL to be relative to the theme root. 3315 if ( ! str_starts_with( $url, 'file:./' ) ) { 3316 continue; 3317 } 3318 3319 $src[ $key ] = get_theme_file_uri( str_replace( 'file:./', '', $url ) ); 3320 } 3321 3322 return $src; 3323 }; 3324 3325 /** 3326 * Converts the font-face properties (i.e. keys) into kebab-case. 3327 * 3328 * @since 6.0.0 3329 * 3330 * @param array $font_face Font face to convert. 3331 * @return array Font faces with each property in kebab-case format. 3332 */ 3333 $fn_convert_keys_to_kebab_case = static function( array $font_face ) { 3334 foreach ( $font_face as $property => $value ) { 3335 $kebab_case = _wp_to_kebab_case( $property ); 3336 $font_face[ $kebab_case ] = $value; 3337 if ( $kebab_case !== $property ) { 3338 unset( $font_face[ $property ] ); 3339 } 3340 } 3341 3342 return $font_face; 3343 }; 3344 3345 /** 3346 * Validates a webfont. 3347 * 3348 * @since 6.0.0 3349 * 3350 * @param array $webfont The webfont arguments. 3351 * @return array|false The validated webfont arguments, or false if the webfont is invalid. 3352 */ 3353 $fn_validate_webfont = static function( $webfont ) { 3354 $webfont = wp_parse_args( 3355 $webfont, 3356 array( 3357 'font-family' => '', 3358 'font-style' => 'normal', 3359 'font-weight' => '400', 3360 'font-display' => 'fallback', 3361 'src' => array(), 3362 ) 3363 ); 3364 3365 // Check the font-family. 3366 if ( empty( $webfont['font-family'] ) || ! is_string( $webfont['font-family'] ) ) { 3367 trigger_error( __( 'Webfont font family must be a non-empty string.' ) ); 3368 3369 return false; 3370 } 3371 3372 // Check that the `src` property is defined and a valid type. 3373 if ( empty( $webfont['src'] ) || ( ! is_string( $webfont['src'] ) && ! is_array( $webfont['src'] ) ) ) { 3374 trigger_error( __( 'Webfont src must be a non-empty string or an array of strings.' ) ); 3375 3376 return false; 3377 } 3378 3379 // Validate the `src` property. 3380 foreach ( (array) $webfont['src'] as $src ) { 3381 if ( ! is_string( $src ) || '' === trim( $src ) ) { 3382 trigger_error( __( 'Each webfont src must be a non-empty string.' ) ); 3383 3384 return false; 3385 } 3386 } 3387 3388 // Check the font-weight. 3389 if ( ! is_string( $webfont['font-weight'] ) && ! is_int( $webfont['font-weight'] ) ) { 3390 trigger_error( __( 'Webfont font weight must be a properly formatted string or integer.' ) ); 3391 3392 return false; 3393 } 3394 3395 // Check the font-display. 3396 if ( ! in_array( $webfont['font-display'], array( 'auto', 'block', 'fallback', 'swap' ), true ) ) { 3397 $webfont['font-display'] = 'fallback'; 3398 } 3399 3400 $valid_props = array( 3401 'ascend-override', 3402 'descend-override', 3403 'font-display', 3404 'font-family', 3405 'font-stretch', 3406 'font-style', 3407 'font-weight', 3408 'font-variant', 3409 'font-feature-settings', 3410 'font-variation-settings', 3411 'line-gap-override', 3412 'size-adjust', 3413 'src', 3414 'unicode-range', 3415 ); 3416 3417 foreach ( $webfont as $prop => $value ) { 3418 if ( ! in_array( $prop, $valid_props, true ) ) { 3419 unset( $webfont[ $prop ] ); 3420 } 3421 } 3422 3423 return $webfont; 3424 }; 3425 3426 /** 3427 * Registers webfonts declared in theme.json. 3428 * 3429 * @since 6.0.0 3430 * 3431 * @uses $registered_webfonts To access and update the registered webfonts registry (passed by reference). 3432 * @uses $fn_get_webfonts_from_theme_json To run the function that gets the webfonts from theme.json. 3433 * @uses $fn_convert_keys_to_kebab_case To run the function that converts keys into kebab-case. 3434 * @uses $fn_validate_webfont To run the function that validates each font-face (webfont) from theme.json. 3435 */ 3436 $fn_register_webfonts = static function() use ( &$registered_webfonts, $fn_get_webfonts_from_theme_json, $fn_convert_keys_to_kebab_case, $fn_validate_webfont, $fn_transform_src_into_uri ) { 3437 $registered_webfonts = array(); 3438 3439 foreach ( $fn_get_webfonts_from_theme_json() as $webfont ) { 3440 if ( ! is_array( $webfont ) ) { 3441 continue; 3442 } 3443 3444 $webfont = $fn_convert_keys_to_kebab_case( $webfont ); 3445 3446 $webfont = $fn_validate_webfont( $webfont ); 3447 3448 $webfont['src'] = $fn_transform_src_into_uri( (array) $webfont['src'] ); 3449 3450 // Skip if not valid. 3451 if ( empty( $webfont ) ) { 3452 continue; 3453 } 3454 3455 $registered_webfonts[] = $webfont; 3456 } 3457 }; 3458 3459 /** 3460 * Orders 'src' items to optimize for browser support. 3461 * 3462 * @since 6.0.0 3463 * 3464 * @param array $webfont Webfont to process. 3465 * @return array Ordered `src` items. 3466 */ 3467 $fn_order_src = static function( array $webfont ) { 3468 $src = array(); 3469 $src_ordered = array(); 3470 3471 foreach ( $webfont['src'] as $url ) { 3472 // Add data URIs first. 3473 if ( str_starts_with( trim( $url ), 'data:' ) ) { 3474 $src_ordered[] = array( 3475 'url' => $url, 3476 'format' => 'data', 3477 ); 3478 continue; 3479 } 3480 $format = pathinfo( $url, PATHINFO_EXTENSION ); 3481 $src[ $format ] = $url; 3482 } 3483 3484 // Add woff2. 3485 if ( ! empty( $src['woff2'] ) ) { 3486 $src_ordered[] = array( 3487 'url' => sanitize_url( $src['woff2'] ), 3488 'format' => 'woff2', 3489 ); 3490 } 3491 3492 // Add woff. 3493 if ( ! empty( $src['woff'] ) ) { 3494 $src_ordered[] = array( 3495 'url' => sanitize_url( $src['woff'] ), 3496 'format' => 'woff', 3497 ); 3498 } 3499 3500 // Add ttf. 3501 if ( ! empty( $src['ttf'] ) ) { 3502 $src_ordered[] = array( 3503 'url' => sanitize_url( $src['ttf'] ), 3504 'format' => 'truetype', 3505 ); 3506 } 3507 3508 // Add eot. 3509 if ( ! empty( $src['eot'] ) ) { 3510 $src_ordered[] = array( 3511 'url' => sanitize_url( $src['eot'] ), 3512 'format' => 'embedded-opentype', 3513 ); 3514 } 3515 3516 // Add otf. 3517 if ( ! empty( $src['otf'] ) ) { 3518 $src_ordered[] = array( 3519 'url' => sanitize_url( $src['otf'] ), 3520 'format' => 'opentype', 3521 ); 3522 } 3523 $webfont['src'] = $src_ordered; 3524 3525 return $webfont; 3526 }; 3527 3528 /** 3529 * Compiles the 'src' into valid CSS. 3530 * 3531 * @since 6.0.0 3532 * @since 6.2.0 Removed local() CSS. 3533 * 3534 * @param string $font_family Font family. 3535 * @param array $value Value to process. 3536 * @return string The CSS. 3537 */ 3538 $fn_compile_src = static function( $font_family, array $value ) { 3539 $src = ''; 3540 3541 foreach ( $value as $item ) { 3542 3543 if ( 3544 str_starts_with( $item['url'], site_url() ) || 3545 str_starts_with( $item['url'], home_url() ) 3546 ) { 3547 $item['url'] = wp_make_link_relative( $item['url'] ); 3548 } 3549 3550 $src .= ( 'data' === $item['format'] ) 3551 ? ", url({$item['url']})" 3552 : ", url('{$item['url']}') format('{$item['format']}')"; 3553 } 3554 3555 $src = ltrim( $src, ', ' ); 3556 3557 return $src; 3558 }; 3559 3560 /** 3561 * Compiles the font variation settings. 3562 * 3563 * @since 6.0.0 3564 * 3565 * @param array $font_variation_settings Array of font variation settings. 3566 * @return string The CSS. 3567 */ 3568 $fn_compile_variations = static function( array $font_variation_settings ) { 3569 $variations = ''; 3570 3571 foreach ( $font_variation_settings as $key => $value ) { 3572 $variations .= "$key $value"; 3573 } 3574 3575 return $variations; 3576 }; 3577 3578 /** 3579 * Builds the font-family's CSS. 3580 * 3581 * @since 6.0.0 3582 * 3583 * @uses $fn_compile_src To run the function that compiles the src. 3584 * @uses $fn_compile_variations To run the function that compiles the variations. 3585 * 3586 * @param array $webfont Webfont to process. 3587 * @return string This font-family's CSS. 3588 */ 3589 $fn_build_font_face_css = static function( array $webfont ) use ( $fn_compile_src, $fn_compile_variations ) { 3590 $css = ''; 3591 3592 // Wrap font-family in quotes if it contains spaces. 3593 if ( 3594 str_contains( $webfont['font-family'], ' ' ) && 3595 ! str_contains( $webfont['font-family'], '"' ) && 3596 ! str_contains( $webfont['font-family'], "'" ) 3597 ) { 3598 $webfont['font-family'] = '"' . $webfont['font-family'] . '"'; 3599 } 3600 3601 foreach ( $webfont as $key => $value ) { 3602 /* 3603 * Skip "provider", since it's for internal API use, 3604 * and not a valid CSS property. 3605 */ 3606 if ( 'provider' === $key ) { 3607 continue; 3608 } 3609 3610 // Compile the "src" parameter. 3611 if ( 'src' === $key ) { 3612 $value = $fn_compile_src( $webfont['font-family'], $value ); 3613 } 3614 3615 // If font-variation-settings is an array, convert it to a string. 3616 if ( 'font-variation-settings' === $key && is_array( $value ) ) { 3617 $value = $fn_compile_variations( $value ); 3618 } 3619 3620 if ( ! empty( $value ) ) { 3621 $css .= "$key:$value;"; 3622 } 3623 } 3624 3625 return $css; 3626 }; 3627 3628 /** 3629 * Gets the '@font-face' CSS styles for locally-hosted font files. 3630 * 3631 * @since 6.0.0 3632 * 3633 * @uses $registered_webfonts To access and update the registered webfonts registry (passed by reference). 3634 * @uses $fn_order_src To run the function that orders the src. 3635 * @uses $fn_build_font_face_css To run the function that builds the font-face CSS. 3636 * 3637 * @return string The `@font-face` CSS. 3638 */ 3639 $fn_get_css = static function() use ( &$registered_webfonts, $fn_order_src, $fn_build_font_face_css ) { 3640 $css = ''; 3641 3642 foreach ( $registered_webfonts as $webfont ) { 3643 // Order the webfont's `src` items to optimize for browser support. 3644 $webfont = $fn_order_src( $webfont ); 3645 3646 // Build the @font-face CSS for this webfont. 3647 $css .= '@font-face{' . $fn_build_font_face_css( $webfont ) . '}'; 3648 } 3649 3650 return $css; 3651 }; 3652 3653 /** 3654 * Generates and enqueues webfonts styles. 3655 * 3656 * @since 6.0.0 3657 * 3658 * @uses $fn_get_css To run the function that gets the CSS. 3659 */ 3660 $fn_generate_and_enqueue_styles = static function() use ( $fn_get_css ) { 3661 // Generate the styles. 3662 $styles = $fn_get_css(); 3663 3664 // Bail out if there are no styles to enqueue. 3665 if ( '' === $styles ) { 3666 return; 3667 } 3668 3669 // Enqueue the stylesheet. 3670 wp_register_style( 'wp-webfonts', '' ); 3671 wp_enqueue_style( 'wp-webfonts' ); 3672 3673 // Add the styles to the stylesheet. 3674 wp_add_inline_style( 'wp-webfonts', $styles ); 3675 }; 3676 3677 /** 3678 * Generates and enqueues editor styles. 3679 * 3680 * @since 6.0.0 3681 * 3682 * @uses $fn_get_css To run the function that gets the CSS. 3683 */ 3684 $fn_generate_and_enqueue_editor_styles = static function() use ( $fn_get_css ) { 3685 // Generate the styles. 3686 $styles = $fn_get_css(); 3687 3688 // Bail out if there are no styles to enqueue. 3689 if ( '' === $styles ) { 3690 return; 3691 } 3692 3693 wp_add_inline_style( 'wp-block-library', $styles ); 3694 }; 3695 3696 add_action( 'wp_loaded', $fn_register_webfonts ); 3697 add_action( 'wp_enqueue_scripts', $fn_generate_and_enqueue_styles ); 3698 add_action( 'admin_init', $fn_generate_and_enqueue_editor_styles ); 3699 } 3700 3701 /** 3702 * Loads classic theme styles on classic themes in the frontend. 3703 * 3704 * This is needed for backwards compatibility for button blocks specifically. 3705 * 3706 * @since 6.1.0 3707 */ 3708 function wp_enqueue_classic_theme_styles() { 3709 if ( ! wp_theme_has_theme_json() ) { 3710 $suffix = wp_scripts_get_suffix(); 3711 wp_register_style( 'classic-theme-styles', '/' . WPINC . "/css/classic-themes$suffix.css" ); 3712 wp_enqueue_style( 'classic-theme-styles' ); 3713 } 3714 } 3715 3716 /** 3717 * Loads classic theme styles on classic themes in the editor. 3718 * 3719 * This is needed for backwards compatibility for button blocks specifically. 3720 * 3721 * @since 6.1.0 3722 * 3723 * @param array $editor_settings The array of editor settings. 3724 * @return array A filtered array of editor settings. 3725 */ 3726 function wp_add_editor_classic_theme_styles( $editor_settings ) { 3727 if ( wp_theme_has_theme_json() ) { 3728 return $editor_settings; 3729 } 3730 3731 $suffix = wp_scripts_get_suffix(); 3732 $classic_theme_styles = ABSPATH . WPINC . "/css/classic-themes$suffix.css"; 3733 3734 // This follows the pattern of get_block_editor_theme_styles, 3735 // but we can't use get_block_editor_theme_styles directly as it 3736 // only handles external files or theme files. 3737 $classic_theme_styles_settings = array( 3738 'css' => file_get_contents( $classic_theme_styles ), 3739 '__unstableType' => 'core', 3740 'isGlobalStyles' => false, 3741 ); 3742 3743 // Add these settings to the start of the array so that themes can override them. 3744 array_unshift( $editor_settings['styles'], $classic_theme_styles_settings ); 3745 3746 return $editor_settings; 3747 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Sun Jun 4 08:20:02 2023 | Cross-referenced by PHPXref |