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