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