wp/wp-includes/script-loader.php
changeset 19 3d72ae0968f4
parent 18 be944660c56a
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
    37 /**
    37 /**
    38  * Registers TinyMCE scripts.
    38  * Registers TinyMCE scripts.
    39  *
    39  *
    40  * @since 5.0.0
    40  * @since 5.0.0
    41  *
    41  *
       
    42  * @global string $tinymce_version
       
    43  * @global bool   $concatenate_scripts
       
    44  * @global bool   $compress_scripts
       
    45  *
    42  * @param WP_Scripts $scripts            WP_Scripts object.
    46  * @param WP_Scripts $scripts            WP_Scripts object.
    43  * @param bool       $force_uncompressed Whether to forcibly prevent gzip compression. Default false.
    47  * @param bool       $force_uncompressed Whether to forcibly prevent gzip compression. Default false.
    44  */
    48  */
    45 function wp_register_tinymce_scripts( $scripts, $force_uncompressed = false ) {
    49 function wp_register_tinymce_scripts( $scripts, $force_uncompressed = false ) {
    46 	global $tinymce_version, $concatenate_scripts, $compress_scripts;
    50 	global $tinymce_version, $concatenate_scripts, $compress_scripts;
       
    51 
    47 	$suffix     = wp_scripts_get_suffix();
    52 	$suffix     = wp_scripts_get_suffix();
    48 	$dev_suffix = wp_scripts_get_suffix( 'dev' );
    53 	$dev_suffix = wp_scripts_get_suffix( 'dev' );
    49 
    54 
    50 	script_concat_settings();
    55 	script_concat_settings();
    51 
    56 
    69  * `js/dist/vendor/` location.
    74  * `js/dist/vendor/` location.
    70  *
    75  *
    71  * For the order of `$scripts->add` see `wp_default_scripts`.
    76  * For the order of `$scripts->add` see `wp_default_scripts`.
    72  *
    77  *
    73  * @since 5.0.0
    78  * @since 5.0.0
       
    79  *
       
    80  * @global WP_Locale $wp_locale WordPress date and time locale object.
    74  *
    81  *
    75  * @param WP_Scripts $scripts WP_Scripts object.
    82  * @param WP_Scripts $scripts WP_Scripts object.
    76  */
    83  */
    77 function wp_default_packages_vendor( $scripts ) {
    84 function wp_default_packages_vendor( $scripts ) {
    78 	global $wp_locale;
    85 	global $wp_locale;
    94 		'wp-polyfill-object-fit',
   101 		'wp-polyfill-object-fit',
    95 		'wp-polyfill' => array( 'regenerator-runtime' ),
   102 		'wp-polyfill' => array( 'regenerator-runtime' ),
    96 	);
   103 	);
    97 
   104 
    98 	$vendor_scripts_versions = array(
   105 	$vendor_scripts_versions = array(
    99 		'react'                       => '16.13.1',
   106 		'react'                       => '17.0.1',
   100 		'react-dom'                   => '16.13.1',
   107 		'react-dom'                   => '17.0.1',
   101 		'regenerator-runtime'         => '0.13.7',
   108 		'regenerator-runtime'         => '0.13.9',
   102 		'moment'                      => '2.29.1',
   109 		'moment'                      => '2.29.4',
   103 		'lodash'                      => '4.17.19',
   110 		'lodash'                      => '4.17.19',
   104 		'wp-polyfill-fetch'           => '3.0.0',
   111 		'wp-polyfill-fetch'           => '3.6.2',
   105 		'wp-polyfill-formdata'        => '4.0.0',
   112 		'wp-polyfill-formdata'        => '4.0.10',
   106 		'wp-polyfill-node-contains'   => '3.105.0',
   113 		'wp-polyfill-node-contains'   => '4.0.0',
   107 		'wp-polyfill-url'             => '3.6.4',
   114 		'wp-polyfill-url'             => '3.6.4',
   108 		'wp-polyfill-dom-rect'        => '3.104.0',
   115 		'wp-polyfill-dom-rect'        => '4.0.0',
   109 		'wp-polyfill-element-closest' => '2.0.2',
   116 		'wp-polyfill-element-closest' => '2.0.2',
   110 		'wp-polyfill-object-fit'      => '2.3.5',
   117 		'wp-polyfill-object-fit'      => '2.3.5',
   111 		'wp-polyfill'                 => '3.15.0',
   118 		'wp-polyfill'                 => '3.15.0',
   112 	);
   119 	);
   113 
   120 
   206 
   213 
   207 	return $polyfill;
   214 	return $polyfill;
   208 }
   215 }
   209 
   216 
   210 /**
   217 /**
       
   218  * Registers development scripts that integrate with `@wordpress/scripts`.
       
   219  *
       
   220  * @see https://github.com/WordPress/gutenberg/tree/trunk/packages/scripts#start
       
   221  *
       
   222  * @since 6.0.0
       
   223  *
       
   224  * @param WP_Scripts $scripts WP_Scripts object.
       
   225  */
       
   226 function wp_register_development_scripts( $scripts ) {
       
   227 	if (
       
   228 		! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG
       
   229 		|| empty( $scripts->registered['react'] )
       
   230 	) {
       
   231 		return;
       
   232 	}
       
   233 
       
   234 	$development_scripts = array(
       
   235 		'react-refresh-entry',
       
   236 		'react-refresh-runtime',
       
   237 	);
       
   238 
       
   239 	foreach ( $development_scripts as $script_name ) {
       
   240 		$assets = include ABSPATH . WPINC . '/assets/script-loader-' . $script_name . '.php';
       
   241 		if ( ! is_array( $assets ) ) {
       
   242 			return;
       
   243 		}
       
   244 		$scripts->add(
       
   245 			'wp-' . $script_name,
       
   246 			'/wp-includes/js/dist/development/' . $script_name . '.js',
       
   247 			$assets['dependencies'],
       
   248 			$assets['version']
       
   249 		);
       
   250 	}
       
   251 
       
   252 	// See https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/TROUBLESHOOTING.md#externalising-react.
       
   253 	$scripts->registered['react']->deps[] = 'wp-react-refresh-entry';
       
   254 }
       
   255 
       
   256 /**
   211  * Registers all the WordPress packages scripts that are in the standardized
   257  * Registers all the WordPress packages scripts that are in the standardized
   212  * `js/dist/` location.
   258  * `js/dist/` location.
   213  *
   259  *
   214  * For the order of `$scripts->add` see `wp_default_scripts`.
   260  * For the order of `$scripts->add` see `wp_default_scripts`.
   215  *
   261  *
   218  * @param WP_Scripts $scripts WP_Scripts object.
   264  * @param WP_Scripts $scripts WP_Scripts object.
   219  */
   265  */
   220 function wp_default_packages_scripts( $scripts ) {
   266 function wp_default_packages_scripts( $scripts ) {
   221 	$suffix = wp_scripts_get_suffix();
   267 	$suffix = wp_scripts_get_suffix();
   222 
   268 
   223 	// Expects multidimensional array like:
   269 	/*
   224 	//	'a11y.js' => array('dependencies' => array(...), 'version' => '...'),
   270 	 * Expects multidimensional array like:
   225 	//	'annotations.js' => array('dependencies' => array(...), 'version' => '...'),
   271 	 *
   226 	//	'api-fetch.js' => array(...
   272 	 *     'a11y.js' => array('dependencies' => array(...), 'version' => '...'),
       
   273 	 *     'annotations.js' => array('dependencies' => array(...), 'version' => '...'),
       
   274 	 *     'api-fetch.js' => array(...
       
   275 	 */
   227 	$assets = include ABSPATH . WPINC . '/assets/script-loader-packages.php';
   276 	$assets = include ABSPATH . WPINC . '/assets/script-loader-packages.php';
   228 
   277 
   229 	foreach ( $assets as $package_name => $package_data ) {
   278 	foreach ( $assets as $package_name => $package_data ) {
   230 		$basename = basename( $package_name, '.js' );
   279 		$basename = basename( $package_name, '.js' );
   231 		$handle   = 'wp-' . $basename;
   280 		$handle   = 'wp-' . $basename;
   272 /**
   321 /**
   273  * Adds inline scripts required for the WordPress JavaScript packages.
   322  * Adds inline scripts required for the WordPress JavaScript packages.
   274  *
   323  *
   275  * @since 5.0.0
   324  * @since 5.0.0
   276  *
   325  *
       
   326  * @global WP_Locale $wp_locale WordPress date and time locale object.
       
   327  *
   277  * @param WP_Scripts $scripts WP_Scripts object.
   328  * @param WP_Scripts $scripts WP_Scripts object.
   278  */
   329  */
   279 function wp_default_packages_inline_scripts( $scripts ) {
   330 function wp_default_packages_inline_scripts( $scripts ) {
   280 	global $wp_locale;
   331 	global $wp_locale;
   281 
   332 
   295 		implode(
   346 		implode(
   296 			"\n",
   347 			"\n",
   297 			array(
   348 			array(
   298 				sprintf(
   349 				sprintf(
   299 					'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );',
   350 					'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );',
   300 					( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' )
   351 					wp_installing() ? '' : wp_create_nonce( 'wp_rest' )
   301 				),
   352 				),
   302 				'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );',
   353 				'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );',
   303 				'wp.apiFetch.use( wp.apiFetch.mediaUploadMiddleware );',
   354 				'wp.apiFetch.use( wp.apiFetch.mediaUploadMiddleware );',
   304 				sprintf(
   355 				sprintf(
   305 					'wp.apiFetch.nonceEndpoint = "%s";',
   356 					'wp.apiFetch.nonceEndpoint = "%s";',
   328 	// Calculate the timezone abbr (EDT, PST) if possible.
   379 	// Calculate the timezone abbr (EDT, PST) if possible.
   329 	$timezone_string = get_option( 'timezone_string', 'UTC' );
   380 	$timezone_string = get_option( 'timezone_string', 'UTC' );
   330 	$timezone_abbr   = '';
   381 	$timezone_abbr   = '';
   331 
   382 
   332 	if ( ! empty( $timezone_string ) ) {
   383 	if ( ! empty( $timezone_string ) ) {
   333 		$timezone_date = new DateTime( null, new DateTimeZone( $timezone_string ) );
   384 		$timezone_date = new DateTime( 'now', new DateTimeZone( $timezone_string ) );
   334 		$timezone_abbr = $timezone_date->format( 'T' );
   385 		$timezone_abbr = $timezone_date->format( 'T' );
   335 	}
   386 	}
   336 
   387 
   337 	$scripts->add_inline_script(
   388 	$scripts->add_inline_script(
   338 		'wp-date',
   389 		'wp-date',
   546  *
   597  *
   547  * @param WP_Scripts $scripts WP_Scripts object.
   598  * @param WP_Scripts $scripts WP_Scripts object.
   548  */
   599  */
   549 function wp_default_packages( $scripts ) {
   600 function wp_default_packages( $scripts ) {
   550 	wp_default_packages_vendor( $scripts );
   601 	wp_default_packages_vendor( $scripts );
       
   602 	wp_register_development_scripts( $scripts );
   551 	wp_register_tinymce_scripts( $scripts );
   603 	wp_register_tinymce_scripts( $scripts );
   552 	wp_default_packages_scripts( $scripts );
   604 	wp_default_packages_scripts( $scripts );
   553 
   605 
   554 	if ( did_action( 'init' ) ) {
   606 	if ( did_action( 'init' ) ) {
   555 		wp_default_packages_inline_scripts( $scripts );
   607 		wp_default_packages_inline_scripts( $scripts );
   593 
   645 
   594 	return $suffixes['suffix'];
   646 	return $suffixes['suffix'];
   595 }
   647 }
   596 
   648 
   597 /**
   649 /**
   598  * Register all WordPress scripts.
   650  * Registers all WordPress scripts.
   599  *
   651  *
   600  * Localizes some of them.
   652  * Localizes some of them.
   601  * args order: `$scripts->add( 'handle', 'url', 'dependencies', 'query-string', 1 );`
   653  * args order: `$scripts->add( 'handle', 'url', 'dependencies', 'query-string', 1 );`
   602  * when last arg === 1 queues the script for the footer
   654  * when last arg === 1 queues the script for the footer
   603  *
   655  *
   678 
   730 
   679 	$scripts->add( 'colorpicker', "/wp-includes/js/colorpicker$suffix.js", array( 'prototype' ), '3517m' );
   731 	$scripts->add( 'colorpicker', "/wp-includes/js/colorpicker$suffix.js", array( 'prototype' ), '3517m' );
   680 
   732 
   681 	$scripts->add( 'editor', "/wp-admin/js/editor$suffix.js", array( 'utils', 'jquery' ), false, 1 );
   733 	$scripts->add( 'editor', "/wp-admin/js/editor$suffix.js", array( 'utils', 'jquery' ), false, 1 );
   682 
   734 
   683 	$scripts->add( 'clipboard', "/wp-includes/js/clipboard$suffix.js", array(), false, 1 );
   735 	$scripts->add( 'clipboard', "/wp-includes/js/clipboard$suffix.js", array(), '2.0.10', 1 );
   684 
   736 
   685 	$scripts->add( 'wp-ajax-response', "/wp-includes/js/wp-ajax-response$suffix.js", array( 'jquery' ), false, 1 );
   737 	$scripts->add( 'wp-ajax-response', "/wp-includes/js/wp-ajax-response$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 );
   686 	did_action( 'init' ) && $scripts->localize(
   738 	did_action( 'init' ) && $scripts->localize(
   687 		'wp-ajax-response',
   739 		'wp-ajax-response',
   688 		'wpAjax',
   740 		'wpAjax',
   689 		array(
   741 		array(
   690 			'noPerm' => __( 'Sorry, you are not allowed to do that.' ),
   742 			'noPerm' => __( 'Sorry, you are not allowed to do that.' ),
   697 	did_action( 'init' ) && $scripts->localize(
   749 	did_action( 'init' ) && $scripts->localize(
   698 		'wp-api-request',
   750 		'wp-api-request',
   699 		'wpApiSettings',
   751 		'wpApiSettings',
   700 		array(
   752 		array(
   701 			'root'          => esc_url_raw( get_rest_url() ),
   753 			'root'          => esc_url_raw( get_rest_url() ),
   702 			'nonce'         => ( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ),
   754 			'nonce'         => wp_installing() ? '' : wp_create_nonce( 'wp_rest' ),
   703 			'versionString' => 'wp/v2/',
   755 			'versionString' => 'wp/v2/',
   704 		)
   756 		)
   705 	);
   757 	);
   706 
   758 
   707 	$scripts->add( 'wp-pointer', "/wp-includes/js/wp-pointer$suffix.js", array( 'jquery-ui-core' ), false, 1 );
   759 	$scripts->add( 'wp-pointer', "/wp-includes/js/wp-pointer$suffix.js", array( 'jquery-ui-core' ), false, 1 );
   751 	// Full jQuery UI.
   803 	// Full jQuery UI.
   752 	// The build process in 1.12.1 has changed significantly.
   804 	// The build process in 1.12.1 has changed significantly.
   753 	// In order to keep backwards compatibility, and to keep the optimized loading,
   805 	// In order to keep backwards compatibility, and to keep the optimized loading,
   754 	// the source files were flattened and included with some modifications for AMD loading.
   806 	// the source files were flattened and included with some modifications for AMD loading.
   755 	// A notable change is that 'jquery-ui-core' now contains 'jquery-ui-position' and 'jquery-ui-widget'.
   807 	// A notable change is that 'jquery-ui-core' now contains 'jquery-ui-position' and 'jquery-ui-widget'.
   756 	$scripts->add( 'jquery-ui-core', "/wp-includes/js/jquery/ui/core$suffix.js", array( 'jquery' ), '1.12.1', 1 );
   808 	$scripts->add( 'jquery-ui-core', "/wp-includes/js/jquery/ui/core$suffix.js", array( 'jquery' ), '1.13.1', 1 );
   757 	$scripts->add( 'jquery-effects-core', "/wp-includes/js/jquery/ui/effect$suffix.js", array( 'jquery' ), '1.12.1', 1 );
   809 	$scripts->add( 'jquery-effects-core', "/wp-includes/js/jquery/ui/effect$suffix.js", array( 'jquery' ), '1.13.1', 1 );
   758 
   810 
   759 	$scripts->add( 'jquery-effects-blind', "/wp-includes/js/jquery/ui/effect-blind$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   811 	$scripts->add( 'jquery-effects-blind', "/wp-includes/js/jquery/ui/effect-blind$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   760 	$scripts->add( 'jquery-effects-bounce', "/wp-includes/js/jquery/ui/effect-bounce$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   812 	$scripts->add( 'jquery-effects-bounce', "/wp-includes/js/jquery/ui/effect-bounce$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   761 	$scripts->add( 'jquery-effects-clip', "/wp-includes/js/jquery/ui/effect-clip$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   813 	$scripts->add( 'jquery-effects-clip', "/wp-includes/js/jquery/ui/effect-clip$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   762 	$scripts->add( 'jquery-effects-drop', "/wp-includes/js/jquery/ui/effect-drop$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   814 	$scripts->add( 'jquery-effects-drop', "/wp-includes/js/jquery/ui/effect-drop$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   763 	$scripts->add( 'jquery-effects-explode', "/wp-includes/js/jquery/ui/effect-explode$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   815 	$scripts->add( 'jquery-effects-explode', "/wp-includes/js/jquery/ui/effect-explode$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   764 	$scripts->add( 'jquery-effects-fade', "/wp-includes/js/jquery/ui/effect-fade$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   816 	$scripts->add( 'jquery-effects-fade', "/wp-includes/js/jquery/ui/effect-fade$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   765 	$scripts->add( 'jquery-effects-fold', "/wp-includes/js/jquery/ui/effect-fold$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   817 	$scripts->add( 'jquery-effects-fold', "/wp-includes/js/jquery/ui/effect-fold$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   766 	$scripts->add( 'jquery-effects-highlight', "/wp-includes/js/jquery/ui/effect-highlight$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   818 	$scripts->add( 'jquery-effects-highlight', "/wp-includes/js/jquery/ui/effect-highlight$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   767 	$scripts->add( 'jquery-effects-puff', "/wp-includes/js/jquery/ui/effect-puff$suffix.js", array( 'jquery-effects-core', 'jquery-effects-scale' ), '1.12.1', 1 );
   819 	$scripts->add( 'jquery-effects-puff', "/wp-includes/js/jquery/ui/effect-puff$suffix.js", array( 'jquery-effects-core', 'jquery-effects-scale' ), '1.13.1', 1 );
   768 	$scripts->add( 'jquery-effects-pulsate', "/wp-includes/js/jquery/ui/effect-pulsate$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   820 	$scripts->add( 'jquery-effects-pulsate', "/wp-includes/js/jquery/ui/effect-pulsate$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   769 	$scripts->add( 'jquery-effects-scale', "/wp-includes/js/jquery/ui/effect-scale$suffix.js", array( 'jquery-effects-core', 'jquery-effects-size' ), '1.12.1', 1 );
   821 	$scripts->add( 'jquery-effects-scale', "/wp-includes/js/jquery/ui/effect-scale$suffix.js", array( 'jquery-effects-core', 'jquery-effects-size' ), '1.13.1', 1 );
   770 	$scripts->add( 'jquery-effects-shake', "/wp-includes/js/jquery/ui/effect-shake$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   822 	$scripts->add( 'jquery-effects-shake', "/wp-includes/js/jquery/ui/effect-shake$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   771 	$scripts->add( 'jquery-effects-size', "/wp-includes/js/jquery/ui/effect-size$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   823 	$scripts->add( 'jquery-effects-size', "/wp-includes/js/jquery/ui/effect-size$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   772 	$scripts->add( 'jquery-effects-slide', "/wp-includes/js/jquery/ui/effect-slide$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   824 	$scripts->add( 'jquery-effects-slide', "/wp-includes/js/jquery/ui/effect-slide$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   773 	$scripts->add( 'jquery-effects-transfer', "/wp-includes/js/jquery/ui/effect-transfer$suffix.js", array( 'jquery-effects-core' ), '1.12.1', 1 );
   825 	$scripts->add( 'jquery-effects-transfer', "/wp-includes/js/jquery/ui/effect-transfer$suffix.js", array( 'jquery-effects-core' ), '1.13.1', 1 );
   774 
   826 
   775 	// Widgets
   827 	// Widgets
   776 	$scripts->add( 'jquery-ui-accordion', "/wp-includes/js/jquery/ui/accordion$suffix.js", array( 'jquery-ui-core' ), '1.12.1', 1 );
   828 	$scripts->add( 'jquery-ui-accordion', "/wp-includes/js/jquery/ui/accordion$suffix.js", array( 'jquery-ui-core' ), '1.13.1', 1 );
   777 	$scripts->add( 'jquery-ui-autocomplete', "/wp-includes/js/jquery/ui/autocomplete$suffix.js", array( 'jquery-ui-menu', 'wp-a11y' ), '1.12.1', 1 );
   829 	$scripts->add( 'jquery-ui-autocomplete', "/wp-includes/js/jquery/ui/autocomplete$suffix.js", array( 'jquery-ui-menu', 'wp-a11y' ), '1.13.1', 1 );
   778 	$scripts->add( 'jquery-ui-button', "/wp-includes/js/jquery/ui/button$suffix.js", array( 'jquery-ui-core', 'jquery-ui-controlgroup', 'jquery-ui-checkboxradio' ), '1.12.1', 1 );
   830 	$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.1', 1 );
   779 	$scripts->add( 'jquery-ui-datepicker', "/wp-includes/js/jquery/ui/datepicker$suffix.js", array( 'jquery-ui-core' ), '1.12.1', 1 );
   831 	$scripts->add( 'jquery-ui-datepicker', "/wp-includes/js/jquery/ui/datepicker$suffix.js", array( 'jquery-ui-core' ), '1.13.1', 1 );
   780 	$scripts->add( 'jquery-ui-dialog', "/wp-includes/js/jquery/ui/dialog$suffix.js", array( 'jquery-ui-resizable', 'jquery-ui-draggable', 'jquery-ui-button' ), '1.12.1', 1 );
   832 	$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.1', 1 );
   781 	$scripts->add( 'jquery-ui-menu', "/wp-includes/js/jquery/ui/menu$suffix.js", array( 'jquery-ui-core' ), '1.12.1', 1 );
   833 	$scripts->add( 'jquery-ui-menu', "/wp-includes/js/jquery/ui/menu$suffix.js", array( 'jquery-ui-core' ), '1.13.1', 1 );
   782 	$scripts->add( 'jquery-ui-mouse', "/wp-includes/js/jquery/ui/mouse$suffix.js", array( 'jquery-ui-core' ), '1.12.1', 1 );
   834 	$scripts->add( 'jquery-ui-mouse', "/wp-includes/js/jquery/ui/mouse$suffix.js", array( 'jquery-ui-core' ), '1.13.1', 1 );
   783 	$scripts->add( 'jquery-ui-progressbar', "/wp-includes/js/jquery/ui/progressbar$suffix.js", array( 'jquery-ui-core' ), '1.12.1', 1 );
   835 	$scripts->add( 'jquery-ui-progressbar', "/wp-includes/js/jquery/ui/progressbar$suffix.js", array( 'jquery-ui-core' ), '1.13.1', 1 );
   784 	$scripts->add( 'jquery-ui-selectmenu', "/wp-includes/js/jquery/ui/selectmenu$suffix.js", array( 'jquery-ui-menu' ), '1.12.1', 1 );
   836 	$scripts->add( 'jquery-ui-selectmenu', "/wp-includes/js/jquery/ui/selectmenu$suffix.js", array( 'jquery-ui-menu' ), '1.13.1', 1 );
   785 	$scripts->add( 'jquery-ui-slider', "/wp-includes/js/jquery/ui/slider$suffix.js", array( 'jquery-ui-mouse' ), '1.12.1', 1 );
   837 	$scripts->add( 'jquery-ui-slider', "/wp-includes/js/jquery/ui/slider$suffix.js", array( 'jquery-ui-mouse' ), '1.13.1', 1 );
   786 	$scripts->add( 'jquery-ui-spinner', "/wp-includes/js/jquery/ui/spinner$suffix.js", array( 'jquery-ui-button' ), '1.12.1', 1 );
   838 	$scripts->add( 'jquery-ui-spinner', "/wp-includes/js/jquery/ui/spinner$suffix.js", array( 'jquery-ui-button' ), '1.13.1', 1 );
   787 	$scripts->add( 'jquery-ui-tabs', "/wp-includes/js/jquery/ui/tabs$suffix.js", array( 'jquery-ui-core' ), '1.12.1', 1 );
   839 	$scripts->add( 'jquery-ui-tabs', "/wp-includes/js/jquery/ui/tabs$suffix.js", array( 'jquery-ui-core' ), '1.13.1', 1 );
   788 	$scripts->add( 'jquery-ui-tooltip', "/wp-includes/js/jquery/ui/tooltip$suffix.js", array( 'jquery-ui-core' ), '1.12.1', 1 );
   840 	$scripts->add( 'jquery-ui-tooltip', "/wp-includes/js/jquery/ui/tooltip$suffix.js", array( 'jquery-ui-core' ), '1.13.1', 1 );
   789 
   841 
   790 	// New in 1.12.1
   842 	// New in 1.12.1
   791 	$scripts->add( 'jquery-ui-checkboxradio', "/wp-includes/js/jquery/ui/checkboxradio$suffix.js", array( 'jquery-ui-core' ), '1.12.1', 1 );
   843 	$scripts->add( 'jquery-ui-checkboxradio', "/wp-includes/js/jquery/ui/checkboxradio$suffix.js", array( 'jquery-ui-core' ), '1.13.1', 1 );
   792 	$scripts->add( 'jquery-ui-controlgroup', "/wp-includes/js/jquery/ui/controlgroup$suffix.js", array( 'jquery-ui-core' ), '1.12.1', 1 );
   844 	$scripts->add( 'jquery-ui-controlgroup', "/wp-includes/js/jquery/ui/controlgroup$suffix.js", array( 'jquery-ui-core' ), '1.13.1', 1 );
   793 
   845 
   794 	// Interactions
   846 	// Interactions
   795 	$scripts->add( 'jquery-ui-draggable', "/wp-includes/js/jquery/ui/draggable$suffix.js", array( 'jquery-ui-mouse' ), '1.12.1', 1 );
   847 	$scripts->add( 'jquery-ui-draggable', "/wp-includes/js/jquery/ui/draggable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.1', 1 );
   796 	$scripts->add( 'jquery-ui-droppable', "/wp-includes/js/jquery/ui/droppable$suffix.js", array( 'jquery-ui-draggable' ), '1.12.1', 1 );
   848 	$scripts->add( 'jquery-ui-droppable', "/wp-includes/js/jquery/ui/droppable$suffix.js", array( 'jquery-ui-draggable' ), '1.13.1', 1 );
   797 	$scripts->add( 'jquery-ui-resizable', "/wp-includes/js/jquery/ui/resizable$suffix.js", array( 'jquery-ui-mouse' ), '1.12.1', 1 );
   849 	$scripts->add( 'jquery-ui-resizable', "/wp-includes/js/jquery/ui/resizable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.1', 1 );
   798 	$scripts->add( 'jquery-ui-selectable', "/wp-includes/js/jquery/ui/selectable$suffix.js", array( 'jquery-ui-mouse' ), '1.12.1', 1 );
   850 	$scripts->add( 'jquery-ui-selectable', "/wp-includes/js/jquery/ui/selectable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.1', 1 );
   799 	$scripts->add( 'jquery-ui-sortable', "/wp-includes/js/jquery/ui/sortable$suffix.js", array( 'jquery-ui-mouse' ), '1.12.1', 1 );
   851 	$scripts->add( 'jquery-ui-sortable', "/wp-includes/js/jquery/ui/sortable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.1', 1 );
   800 
   852 
   801 	// As of 1.12.1 `jquery-ui-position` and `jquery-ui-widget` are part of `jquery-ui-core`.
   853 	// As of 1.12.1 `jquery-ui-position` and `jquery-ui-widget` are part of `jquery-ui-core`.
   802 	// Listed here for back-compat.
   854 	// Listed here for back-compat.
   803 	$scripts->add( 'jquery-ui-position', false, array( 'jquery-ui-core' ), '1.12.1', 1 );
   855 	$scripts->add( 'jquery-ui-position', false, array( 'jquery-ui-core' ), '1.13.1', 1 );
   804 	$scripts->add( 'jquery-ui-widget', false, array( 'jquery-ui-core' ), '1.12.1', 1 );
   856 	$scripts->add( 'jquery-ui-widget', false, array( 'jquery-ui-core' ), '1.13.1', 1 );
   805 
   857 
   806 	// Strings for 'jquery-ui-autocomplete' live region messages.
   858 	// Strings for 'jquery-ui-autocomplete' live region messages.
   807 	did_action( 'init' ) && $scripts->localize(
   859 	did_action( 'init' ) && $scripts->localize(
   808 		'jquery-ui-autocomplete',
   860 		'jquery-ui-autocomplete',
   809 		'uiAutocompleteL10n',
   861 		'uiAutocompleteL10n',
   819 
   871 
   820 	// Deprecated, not used in core, most functionality is included in jQuery 1.3.
   872 	// Deprecated, not used in core, most functionality is included in jQuery 1.3.
   821 	$scripts->add( 'jquery-form', "/wp-includes/js/jquery/jquery.form$suffix.js", array( 'jquery' ), '4.3.0', 1 );
   873 	$scripts->add( 'jquery-form', "/wp-includes/js/jquery/jquery.form$suffix.js", array( 'jquery' ), '4.3.0', 1 );
   822 
   874 
   823 	// jQuery plugins.
   875 	// jQuery plugins.
   824 	$scripts->add( 'jquery-color', '/wp-includes/js/jquery/jquery.color.min.js', array( 'jquery' ), '2.1.2', 1 );
   876 	$scripts->add( 'jquery-color', '/wp-includes/js/jquery/jquery.color.min.js', array( 'jquery' ), '2.2.0', 1 );
   825 	$scripts->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array( 'jquery' ), '20m', 1 );
   877 	$scripts->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array( 'jquery' ), '20m', 1 );
   826 	$scripts->add( 'jquery-query', '/wp-includes/js/jquery/jquery.query.js', array( 'jquery' ), '2.1.7', 1 );
   878 	$scripts->add( 'jquery-query', '/wp-includes/js/jquery/jquery.query.js', array( 'jquery' ), '2.2.3', 1 );
   827 	$scripts->add( 'jquery-serialize-object', '/wp-includes/js/jquery/jquery.serialize-object.js', array( 'jquery' ), '0.2-wp', 1 );
   879 	$scripts->add( 'jquery-serialize-object', '/wp-includes/js/jquery/jquery.serialize-object.js', array( 'jquery' ), '0.2-wp', 1 );
   828 	$scripts->add( 'jquery-hotkeys', "/wp-includes/js/jquery/jquery.hotkeys$suffix.js", array( 'jquery' ), '0.0.2m', 1 );
   880 	$scripts->add( 'jquery-hotkeys', "/wp-includes/js/jquery/jquery.hotkeys$suffix.js", array( 'jquery' ), '0.0.2m', 1 );
   829 	$scripts->add( 'jquery-table-hotkeys', "/wp-includes/js/jquery/jquery.table-hotkeys$suffix.js", array( 'jquery', 'jquery-hotkeys' ), false, 1 );
   881 	$scripts->add( 'jquery-table-hotkeys', "/wp-includes/js/jquery/jquery.table-hotkeys$suffix.js", array( 'jquery', 'jquery-hotkeys' ), false, 1 );
   830 	$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 );
   882 	$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 );
   831 
   883 
   851 			'noiframes'        => __( 'This feature requires inline frames. You have iframes disabled or your browser does not support them.' ),
   903 			'noiframes'        => __( 'This feature requires inline frames. You have iframes disabled or your browser does not support them.' ),
   852 			'loadingAnimation' => includes_url( 'js/thickbox/loadingAnimation.gif' ),
   904 			'loadingAnimation' => includes_url( 'js/thickbox/loadingAnimation.gif' ),
   853 		)
   905 		)
   854 	);
   906 	);
   855 
   907 
   856 	$scripts->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.min.js', array( 'jquery' ), '0.9.12' );
   908 	// Not used in core, replaced by imgAreaSelect.
       
   909 	$scripts->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.min.js', array( 'jquery' ), '0.9.15' );
   857 
   910 
   858 	$scripts->add( 'swfobject', '/wp-includes/js/swfobject.js', array(), '2.2-20120417' );
   911 	$scripts->add( 'swfobject', '/wp-includes/js/swfobject.js', array(), '2.2-20120417' );
   859 
   912 
   860 	// Error messages for Plupload.
   913 	// Error messages for Plupload.
   861 	$uploader_l10n = array(
   914 	$uploader_l10n = array(
   862 		'queue_limit_exceeded'      => __( 'You have attempted to queue too many files.' ),
   915 		'queue_limit_exceeded'      => __( 'You have attempted to queue too many files.' ),
   863 		/* translators: %s: File name. */
   916 		/* translators: %s: File name. */
   864 		'file_exceeds_size_limit'   => __( '%s exceeds the maximum upload size for this site.' ),
   917 		'file_exceeds_size_limit'   => __( '%s exceeds the maximum upload size for this site.' ),
   865 		'zero_byte_file'            => __( 'This file is empty. Please try another.' ),
   918 		'zero_byte_file'            => __( 'This file is empty. Please try another.' ),
   866 		'invalid_filetype'          => __( 'Sorry, this file type is not permitted for security reasons.' ),
   919 		'invalid_filetype'          => __( 'Sorry, you are not allowed to upload this file type.' ),
   867 		'not_an_image'              => __( 'This file is not an image. Please try another.' ),
   920 		'not_an_image'              => __( 'This file is not an image. Please try another.' ),
   868 		'image_memory_exceeded'     => __( 'Memory exceeded. Please try another smaller file.' ),
   921 		'image_memory_exceeded'     => __( 'Memory exceeded. Please try another smaller file.' ),
   869 		'image_dimensions_exceeded' => __( 'This is larger than the maximum size. Please try another.' ),
   922 		'image_dimensions_exceeded' => __( 'This is larger than the maximum size. Please try another.' ),
   870 		'default_error'             => __( 'An error occurred in the upload. Please try again later.' ),
   923 		'default_error'             => __( 'An error occurred in the upload. Please try again later.' ),
   871 		'missing_upload_url'        => __( 'There was a configuration error. Please contact the server administrator.' ),
   924 		'missing_upload_url'        => __( 'There was a configuration error. Please contact the server administrator.' ),
   872 		'upload_limit_exceeded'     => __( 'You may only upload 1 file.' ),
   925 		'upload_limit_exceeded'     => __( 'You may only upload 1 file.' ),
   873 		'http_error'                => __( 'Unexpected response from the server. The file may have been uploaded successfully. Check in the Media Library or reload the page.' ),
   926 		'http_error'                => __( 'Unexpected response from the server. The file may have been uploaded successfully. Check in the Media Library or reload the page.' ),
   874 		'http_error_image'          => __( 'Post-processing of the image failed likely because the server is busy or does not have enough resources. Uploading a smaller image may help. Suggested maximum size is 2500 pixels.' ),
   927 		'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.' ),
   875 		'upload_failed'             => __( 'Upload failed.' ),
   928 		'upload_failed'             => __( 'Upload failed.' ),
   876 		/* translators: 1: Opening link tag, 2: Closing link tag. */
   929 		/* translators: 1: Opening link tag, 2: Closing link tag. */
   877 		'big_upload_failed'         => __( 'Please try uploading this file with the %1$sbrowser uploader%2$s.' ),
   930 		'big_upload_failed'         => __( 'Please try uploading this file with the %1$sbrowser uploader%2$s.' ),
   878 		/* translators: %s: File name. */
   931 		/* translators: %s: File name. */
   879 		'big_upload_queued'         => __( '%s exceeds the maximum upload size for the multi-file uploader when used in your browser.' ),
   932 		'big_upload_queued'         => __( '%s exceeds the maximum upload size for the multi-file uploader when used in your browser.' ),
   913 	$scripts->add( 'comment-reply', "/wp-includes/js/comment-reply$suffix.js", array(), false, 1 );
   966 	$scripts->add( 'comment-reply', "/wp-includes/js/comment-reply$suffix.js", array(), false, 1 );
   914 
   967 
   915 	$scripts->add( 'json2', "/wp-includes/js/json2$suffix.js", array(), '2015-05-03' );
   968 	$scripts->add( 'json2', "/wp-includes/js/json2$suffix.js", array(), '2015-05-03' );
   916 	did_action( 'init' ) && $scripts->add_data( 'json2', 'conditional', 'lt IE 8' );
   969 	did_action( 'init' ) && $scripts->add_data( 'json2', 'conditional', 'lt IE 8' );
   917 
   970 
   918 	$scripts->add( 'underscore', "/wp-includes/js/underscore$dev_suffix.js", array(), '1.13.1', 1 );
   971 	$scripts->add( 'underscore', "/wp-includes/js/underscore$dev_suffix.js", array(), '1.13.3', 1 );
   919 	$scripts->add( 'backbone', "/wp-includes/js/backbone$dev_suffix.js", array( 'underscore', 'jquery' ), '1.4.0', 1 );
   972 	$scripts->add( 'backbone', "/wp-includes/js/backbone$dev_suffix.js", array( 'underscore', 'jquery' ), '1.4.1', 1 );
   920 
   973 
   921 	$scripts->add( 'wp-util', "/wp-includes/js/wp-util$suffix.js", array( 'underscore', 'jquery' ), false, 1 );
   974 	$scripts->add( 'wp-util', "/wp-includes/js/wp-util$suffix.js", array( 'underscore', 'jquery' ), false, 1 );
   922 	did_action( 'init' ) && $scripts->localize(
   975 	did_action( 'init' ) && $scripts->localize(
   923 		'wp-util',
   976 		'wp-util',
   924 		'_wpUtilSettings',
   977 		'_wpUtilSettings',
  1095 	did_action( 'init' ) && $scripts->localize(
  1148 	did_action( 'init' ) && $scripts->localize(
  1096 		'user-profile',
  1149 		'user-profile',
  1097 		'userProfileL10n',
  1150 		'userProfileL10n',
  1098 		array(
  1151 		array(
  1099 			'user_id' => $user_id,
  1152 			'user_id' => $user_id,
  1100 			'nonce'   => ( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'reset-password-for-' . $user_id ),
  1153 			'nonce'   => wp_installing() ? '' : wp_create_nonce( 'reset-password-for-' . $user_id ),
  1101 		)
  1154 		)
  1102 	);
  1155 	);
  1103 
  1156 
  1104 	$scripts->add( 'language-chooser', "/wp-admin/js/language-chooser$suffix.js", array( 'jquery' ), false, 1 );
  1157 	$scripts->add( 'language-chooser', "/wp-admin/js/language-chooser$suffix.js", array( 'jquery' ), false, 1 );
  1105 
  1158 
  1128 
  1181 
  1129 	$scripts->add( 'word-count', "/wp-admin/js/word-count$suffix.js", array(), false, 1 );
  1182 	$scripts->add( 'word-count', "/wp-admin/js/word-count$suffix.js", array(), false, 1 );
  1130 
  1183 
  1131 	$scripts->add( 'media-upload', "/wp-admin/js/media-upload$suffix.js", array( 'thickbox', 'shortcode' ), false, 1 );
  1184 	$scripts->add( 'media-upload', "/wp-admin/js/media-upload$suffix.js", array( 'thickbox', 'shortcode' ), false, 1 );
  1132 
  1185 
  1133 	$scripts->add( 'hoverIntent', "/wp-includes/js/hoverIntent$suffix.js", array( 'jquery' ), '1.10.1', 1 );
  1186 	$scripts->add( 'hoverIntent', "/wp-includes/js/hoverIntent$suffix.js", array( 'jquery' ), '1.10.2', 1 );
  1134 
  1187 
  1135 	// JS-only version of hoverintent (no dependencies).
  1188 	// JS-only version of hoverintent (no dependencies).
  1136 	$scripts->add( 'hoverintent-js', '/wp-includes/js/hoverintent-js.min.js', array(), '2.2.1', 1 );
  1189 	$scripts->add( 'hoverintent-js', '/wp-includes/js/hoverintent-js.min.js', array(), '2.2.1', 1 );
  1137 
  1190 
  1138 	$scripts->add( 'customize-base', "/wp-includes/js/customize-base$suffix.js", array( 'jquery', 'json2', 'underscore' ), false, 1 );
  1191 	$scripts->add( 'customize-base', "/wp-includes/js/customize-base$suffix.js", array( 'jquery', 'json2', 'underscore' ), false, 1 );
  1178 			'trashConfirm'            => __( 'Are you sure you want to discard your unpublished changes?' ),
  1231 			'trashConfirm'            => __( 'Are you sure you want to discard your unpublished changes?' ),
  1179 			/* translators: %s: Display name of the user who has taken over the changeset in customizer. */
  1232 			/* translators: %s: Display name of the user who has taken over the changeset in customizer. */
  1180 			'takenOverMessage'        => __( '%s has taken over and is currently customizing.' ),
  1233 			'takenOverMessage'        => __( '%s has taken over and is currently customizing.' ),
  1181 			/* translators: %s: URL to the Customizer to load the autosaved version. */
  1234 			/* translators: %s: URL to the Customizer to load the autosaved version. */
  1182 			'autosaveNotice'          => __( 'There is a more recent autosave of your changes than the one you are previewing. <a href="%s">Restore the autosave</a>' ),
  1235 			'autosaveNotice'          => __( 'There is a more recent autosave of your changes than the one you are previewing. <a href="%s">Restore the autosave</a>' ),
  1183 			'videoHeaderNotice'       => __( 'This theme doesn&#8217;t support video headers on this page. Navigate to the front page or another page that supports video headers.' ),
  1236 			'videoHeaderNotice'       => __( 'This theme does not support video headers on this page. Navigate to the front page or another page that supports video headers.' ),
  1184 			// Used for overriding the file types allowed in Plupload.
  1237 			// Used for overriding the file types allowed in Plupload.
  1185 			'allowedFiles'            => __( 'Allowed Files' ),
  1238 			'allowedFiles'            => __( 'Allowed Files' ),
  1186 			'customCssError'          => array(
  1239 			'customCssError'          => array(
  1187 				/* translators: %d: Error count. */
  1240 				/* translators: %d: Error count. */
  1188 				'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 ),
  1241 				'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 ),
  1197 				/* translators: %s: Number of invalid settings. */
  1250 				/* translators: %s: Number of invalid settings. */
  1198 				'plural'   => _n( 'Unable to save due to %s invalid setting.', 'Unable to save due to %s invalid settings.', 2 ),
  1251 				'plural'   => _n( 'Unable to save due to %s invalid setting.', 'Unable to save due to %s invalid settings.', 2 ),
  1199 				// @todo This is lacking, as some languages have a dedicated dual form. For proper handling of plurals in JS, see #20491.
  1252 				// @todo This is lacking, as some languages have a dedicated dual form. For proper handling of plurals in JS, see #20491.
  1200 			),
  1253 			),
  1201 			'scheduleDescription'     => __( 'Schedule your customization changes to publish ("go live") at a future date.' ),
  1254 			'scheduleDescription'     => __( 'Schedule your customization changes to publish ("go live") at a future date.' ),
  1202 			'themePreviewUnavailable' => __( 'Sorry, you can&#8217;t 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.' ),
  1255 			'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.' ),
  1203 			'themeInstallUnavailable' => sprintf(
  1256 			'themeInstallUnavailable' => sprintf(
  1204 				/* translators: %s: URL to Add Themes admin screen. */
  1257 				/* translators: %s: URL to Add Themes admin screen. */
  1205 				__( 'You won&#8217;t 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>.' ),
  1258 				__( '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>.' ),
  1206 				esc_url( admin_url( 'theme-install.php' ) )
  1259 				esc_url( admin_url( 'theme-install.php' ) )
  1207 			),
  1260 			),
  1208 			'publishSettings'         => __( 'Publish Settings' ),
  1261 			'publishSettings'         => __( 'Publish Settings' ),
  1209 			'invalidDate'             => __( 'Invalid date.' ),
  1262 			'invalidDate'             => __( 'Invalid date.' ),
  1210 			'invalidValue'            => __( 'Invalid value.' ),
  1263 			'invalidValue'            => __( 'Invalid value.' ),
       
  1264 			'blockThemeNotification'  => sprintf(
       
  1265 				/* translators: 1: Link to Site Editor documentation on HelpHub, 2: HTML button. */
       
  1266 				__( 'Hurray! Your theme supports Full Site Editing with blocks. <a href="%1$s">Tell me more</a>. %2$s' ),
       
  1267 				__( 'https://wordpress.org/support/article/site-editor/' ),
       
  1268 				sprintf(
       
  1269 					'<button type="button" data-action="%1$s" class="button switch-to-editor">%2$s</button>',
       
  1270 					esc_url( admin_url( 'site-editor.php' ) ),
       
  1271 					__( 'Use Site Editor' )
       
  1272 				)
       
  1273 			),
  1211 		)
  1274 		)
  1212 	);
  1275 	);
  1213 	$scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 );
  1276 	$scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 );
  1214 
  1277 
  1215 	$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 );
  1278 	$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 );
  1233 				'post'    => array( 'id' => 0 ),
  1296 				'post'    => array( 'id' => 0 ),
  1234 			),
  1297 			),
  1235 		)
  1298 		)
  1236 	);
  1299 	);
  1237 
  1300 
  1238 	$scripts->add( 'wp-embed', "/wp-includes/js/wp-embed$suffix.js" );
  1301 	$scripts->add( 'wp-embed', "/wp-includes/js/wp-embed$suffix.js", array(), false, 1 );
  1239 
  1302 
  1240 	// To enqueue media-views or media-editor, call wp_enqueue_media().
  1303 	// To enqueue media-views or media-editor, call wp_enqueue_media().
  1241 	// Both rely on numerous settings, styles, and templates to operate correctly.
  1304 	// Both rely on numerous settings, styles, and templates to operate correctly.
  1242 	$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 );
  1305 	$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 );
  1243 	$scripts->set_translations( 'media-views' );
  1306 	$scripts->set_translations( 'media-views' );
  1315 		$scripts->set_translations( 'site-health' );
  1378 		$scripts->set_translations( 'site-health' );
  1316 
  1379 
  1317 		$scripts->add( 'privacy-tools', "/wp-admin/js/privacy-tools$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 );
  1380 		$scripts->add( 'privacy-tools', "/wp-admin/js/privacy-tools$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 );
  1318 		$scripts->set_translations( 'privacy-tools' );
  1381 		$scripts->set_translations( 'privacy-tools' );
  1319 
  1382 
  1320 		$scripts->add( 'updates', "/wp-admin/js/updates$suffix.js", array( 'common', 'jquery', 'wp-util', 'wp-a11y', 'wp-sanitize' ), false, 1 );
  1383 		$scripts->add( 'updates', "/wp-admin/js/updates$suffix.js", array( 'common', 'jquery', 'wp-util', 'wp-a11y', 'wp-sanitize', 'wp-i18n' ), false, 1 );
  1321 		$scripts->set_translations( 'updates' );
  1384 		$scripts->set_translations( 'updates' );
  1322 		did_action( 'init' ) && $scripts->localize(
  1385 		did_action( 'init' ) && $scripts->localize(
  1323 			'updates',
  1386 			'updates',
  1324 			'_wpUpdatesSettings',
  1387 			'_wpUpdatesSettings',
  1325 			array(
  1388 			array(
  1326 				'ajax_nonce' => wp_create_nonce( 'updates' ),
  1389 				'ajax_nonce' => wp_installing() ? '' : wp_create_nonce( 'updates' ),
  1327 			)
  1390 			)
  1328 		);
  1391 		);
  1329 
  1392 
  1330 		$scripts->add( 'farbtastic', '/wp-admin/js/farbtastic.js', array( 'jquery' ), '1.2' );
  1393 		$scripts->add( 'farbtastic', '/wp-admin/js/farbtastic.js', array( 'jquery' ), '1.2' );
  1331 
  1394 
  1332 		$scripts->add( 'iris', '/wp-admin/js/iris.min.js', array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), '1.0.7', 1 );
  1395 		$scripts->add( 'iris', '/wp-admin/js/iris.min.js', array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), '1.1.1', 1 );
  1333 		$scripts->add( 'wp-color-picker', "/wp-admin/js/color-picker$suffix.js", array( 'iris' ), false, 1 );
  1396 		$scripts->add( 'wp-color-picker', "/wp-admin/js/color-picker$suffix.js", array( 'iris' ), false, 1 );
  1334 		$scripts->set_translations( 'wp-color-picker' );
  1397 		$scripts->set_translations( 'wp-color-picker' );
  1335 
  1398 
  1336 		$scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-util', 'wp-a11y', 'wp-date' ), false, 1 );
  1399 		$scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-util', 'wp-a11y', 'wp-date' ), false, 1 );
  1337 		$scripts->set_translations( 'dashboard' );
  1400 		$scripts->set_translations( 'dashboard' );
  1338 
  1401 
  1339 		$scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" );
  1402 		$scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" );
  1340 
  1403 
  1341 		$scripts->add( 'media-grid', "/wp-includes/js/media-grid$suffix.js", array( 'media-editor' ), false, 1 );
  1404 		$scripts->add( 'media-grid', "/wp-includes/js/media-grid$suffix.js", array( 'media-editor' ), false, 1 );
  1342 		$scripts->add( 'media', "/wp-admin/js/media$suffix.js", array( 'jquery' ), false, 1 );
  1405 		$scripts->add( 'media', "/wp-admin/js/media$suffix.js", array( 'jquery', 'clipboard', 'wp-i18n', 'wp-a11y' ), false, 1 );
  1343 		$scripts->set_translations( 'media' );
  1406 		$scripts->set_translations( 'media' );
  1344 
  1407 
  1345 		$scripts->add( 'image-edit', "/wp-admin/js/image-edit$suffix.js", array( 'jquery', 'jquery-ui-core', 'json2', 'imgareaselect', 'wp-a11y' ), false, 1 );
  1408 		$scripts->add( 'image-edit', "/wp-admin/js/image-edit$suffix.js", array( 'jquery', 'jquery-ui-core', 'json2', 'imgareaselect', 'wp-a11y' ), false, 1 );
  1346 		$scripts->set_translations( 'image-edit' );
  1409 		$scripts->set_translations( 'image-edit' );
  1347 
  1410 
  1362 		$scripts->add( 'svg-painter', '/wp-admin/js/svg-painter.js', array( 'jquery' ), false, 1 );
  1425 		$scripts->add( 'svg-painter', '/wp-admin/js/svg-painter.js', array( 'jquery' ), false, 1 );
  1363 	}
  1426 	}
  1364 }
  1427 }
  1365 
  1428 
  1366 /**
  1429 /**
  1367  * Assign default styles to $styles object.
  1430  * Assigns default styles to $styles object.
  1368  *
  1431  *
  1369  * Nothing is returned, because the $styles parameter is passed by reference.
  1432  * Nothing is returned, because the $styles parameter is passed by reference.
  1370  * Meaning that whatever object is passed will be updated without having to
  1433  * Meaning that whatever object is passed will be updated without having to
  1371  * reassign the variable that was passed back to the same value. This saves
  1434  * reassign the variable that was passed back to the same value. This saves
  1372  * memory.
  1435  * memory.
  1374  * Adding default styles is not the only task, it also assigns the base_url
  1437  * Adding default styles is not the only task, it also assigns the base_url
  1375  * property, the default version, and text direction for the object.
  1438  * property, the default version, and text direction for the object.
  1376  *
  1439  *
  1377  * @since 2.6.0
  1440  * @since 2.6.0
  1378  *
  1441  *
       
  1442  * @global array $editor_styles
       
  1443  *
  1379  * @param WP_Styles $styles
  1444  * @param WP_Styles $styles
  1380  */
  1445  */
  1381 function wp_default_styles( $styles ) {
  1446 function wp_default_styles( $styles ) {
       
  1447 	global $editor_styles;
       
  1448 
  1382 	// Include an unmodified $wp_version.
  1449 	// Include an unmodified $wp_version.
  1383 	require ABSPATH . WPINC . '/version.php';
  1450 	require ABSPATH . WPINC . '/version.php';
  1384 
  1451 
  1385 	if ( ! defined( 'SCRIPT_DEBUG' ) ) {
  1452 	if ( ! defined( 'SCRIPT_DEBUG' ) ) {
  1386 		define( 'SCRIPT_DEBUG', false !== strpos( $wp_version, '-src' ) );
  1453 		define( 'SCRIPT_DEBUG', false !== strpos( $wp_version, '-src' ) );
  1481 	$styles->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.css', array(), '5.29.1-alpha-ee20357' );
  1548 	$styles->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.css', array(), '5.29.1-alpha-ee20357' );
  1482 
  1549 
  1483 	// Deprecated CSS.
  1550 	// Deprecated CSS.
  1484 	$styles->add( 'deprecated-media', "/wp-admin/css/deprecated-media$suffix.css" );
  1551 	$styles->add( 'deprecated-media', "/wp-admin/css/deprecated-media$suffix.css" );
  1485 	$styles->add( 'farbtastic', "/wp-admin/css/farbtastic$suffix.css", array(), '1.3u1' );
  1552 	$styles->add( 'farbtastic', "/wp-admin/css/farbtastic$suffix.css", array(), '1.3u1' );
  1486 	$styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.min.css', array(), '0.9.12' );
  1553 	$styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.min.css', array(), '0.9.15' );
  1487 	$styles->add( 'colors-fresh', false, array( 'wp-admin', 'buttons' ) ); // Old handle.
  1554 	$styles->add( 'colors-fresh', false, array( 'wp-admin', 'buttons' ) ); // Old handle.
  1488 	$styles->add( 'open-sans', $open_sans_font_url ); // No longer used in core as of 4.6.
  1555 	$styles->add( 'open-sans', $open_sans_font_url ); // No longer used in core as of 4.6.
  1489 
  1556 
  1490 	// Noto Serif is no longer used by core, but may be relied upon by themes and plugins.
  1557 	// Noto Serif is no longer used by core, but may be relied upon by themes and plugins.
  1491 	$fonts_url = '';
  1558 	$fonts_url = '';
  1529 	// Only load the default layout and margin styles for themes without theme.json file.
  1596 	// Only load the default layout and margin styles for themes without theme.json file.
  1530 	if ( ! WP_Theme_JSON_Resolver::theme_has_support() ) {
  1597 	if ( ! WP_Theme_JSON_Resolver::theme_has_support() ) {
  1531 		$wp_edit_blocks_dependencies[] = 'wp-editor-classic-layout-styles';
  1598 		$wp_edit_blocks_dependencies[] = 'wp-editor-classic-layout-styles';
  1532 	}
  1599 	}
  1533 
  1600 
  1534 	global $editor_styles;
       
  1535 	if ( ! is_array( $editor_styles ) || count( $editor_styles ) === 0 ) {
  1601 	if ( ! is_array( $editor_styles ) || count( $editor_styles ) === 0 ) {
  1536 		// Include opinionated block styles if no $editor_styles are declared, so the editor never appears broken.
  1602 		// Include opinionated block styles if no $editor_styles are declared, so the editor never appears broken.
  1537 		$wp_edit_blocks_dependencies[] = 'wp-block-library-theme';
  1603 		$wp_edit_blocks_dependencies[] = 'wp-block-library-theme';
  1538 	}
  1604 	}
  1539 
  1605 
  1580 			'wp-widgets',
  1646 			'wp-widgets',
  1581 			'wp-block-editor',
  1647 			'wp-block-editor',
  1582 			'wp-edit-blocks',
  1648 			'wp-edit-blocks',
  1583 			'wp-block-library',
  1649 			'wp-block-library',
  1584 			'wp-reusable-blocks',
  1650 			'wp-reusable-blocks',
       
  1651 		),
       
  1652 		'edit-site'            => array(
       
  1653 			'wp-components',
       
  1654 			'wp-block-editor',
       
  1655 			'wp-edit-blocks',
  1585 		),
  1656 		),
  1586 	);
  1657 	);
  1587 
  1658 
  1588 	foreach ( $package_styles as $package => $dependencies ) {
  1659 	foreach ( $package_styles as $package => $dependencies ) {
  1589 		$handle = 'wp-' . $package;
  1660 		$handle = 'wp-' . $package;
  1638 		'wp-block-library',
  1709 		'wp-block-library',
  1639 		'wp-block-directory',
  1710 		'wp-block-directory',
  1640 		'wp-components',
  1711 		'wp-components',
  1641 		'wp-customize-widgets',
  1712 		'wp-customize-widgets',
  1642 		'wp-edit-post',
  1713 		'wp-edit-post',
       
  1714 		'wp-edit-site',
  1643 		'wp-edit-widgets',
  1715 		'wp-edit-widgets',
  1644 		'wp-editor',
  1716 		'wp-editor',
  1645 		'wp-format-library',
  1717 		'wp-format-library',
  1646 		'wp-list-reusable-blocks',
  1718 		'wp-list-reusable-blocks',
  1647 		'wp-reusable-blocks',
  1719 		'wp-reusable-blocks',
  1659 		}
  1731 		}
  1660 	}
  1732 	}
  1661 }
  1733 }
  1662 
  1734 
  1663 /**
  1735 /**
  1664  * Reorder JavaScript scripts array to place prototype before jQuery.
  1736  * Reorders JavaScript scripts array to place prototype before jQuery.
  1665  *
  1737  *
  1666  * @since 2.3.1
  1738  * @since 2.3.1
  1667  *
  1739  *
  1668  * @param array $js_array JavaScript scripts array
  1740  * @param array $js_array JavaScript scripts array
  1669  * @return array Reordered array, if needed.
  1741  * @return array Reordered array, if needed.
  1691 
  1763 
  1692 	return $js_array;
  1764 	return $js_array;
  1693 }
  1765 }
  1694 
  1766 
  1695 /**
  1767 /**
  1696  * Load localized data on print rather than initialization.
  1768  * Loads localized data on print rather than initialization.
  1697  *
  1769  *
  1698  * These localizations require information that may not be loaded even by init.
  1770  * These localizations require information that may not be loaded even by init.
  1699  *
  1771  *
  1700  * @since 2.5.0
  1772  * @since 2.5.0
  1701  */
  1773  */
  1793 			'firstDay'        => absint( get_option( 'start_of_week' ) ),
  1865 			'firstDay'        => absint( get_option( 'start_of_week' ) ),
  1794 			'isRTL'           => $wp_locale->is_rtl(),
  1866 			'isRTL'           => $wp_locale->is_rtl(),
  1795 		)
  1867 		)
  1796 	);
  1868 	);
  1797 
  1869 
  1798 	wp_add_inline_script( 'jquery-ui-datepicker', "jQuery(document).ready(function(jQuery){jQuery.datepicker.setDefaults({$datepicker_defaults});});" );
  1870 	wp_add_inline_script( 'jquery-ui-datepicker', "jQuery(function(jQuery){jQuery.datepicker.setDefaults({$datepicker_defaults});});" );
  1799 }
  1871 }
  1800 
  1872 
  1801 /**
  1873 /**
  1802  * Localizes community events data that needs to be passed to dashboard.js.
  1874  * Localizes community events data that needs to be passed to dashboard.js.
  1803  *
  1875  *
  1971 	$wp_scripts->reset();
  2043 	$wp_scripts->reset();
  1972 	return $wp_scripts->done;
  2044 	return $wp_scripts->done;
  1973 }
  2045 }
  1974 
  2046 
  1975 /**
  2047 /**
  1976  * Print scripts (internal use only)
  2048  * Prints scripts (internal use only)
  1977  *
  2049  *
  1978  * @ignore
  2050  * @ignore
  1979  *
  2051  *
  1980  * @global WP_Scripts $wp_scripts
  2052  * @global WP_Scripts $wp_scripts
  1981  * @global bool       $compress_scripts
  2053  * @global bool       $compress_scripts
  2027  * @global WP_Scripts $wp_scripts
  2099  * @global WP_Scripts $wp_scripts
  2028  *
  2100  *
  2029  * @return array
  2101  * @return array
  2030  */
  2102  */
  2031 function wp_print_head_scripts() {
  2103 function wp_print_head_scripts() {
       
  2104 	global $wp_scripts;
       
  2105 
  2032 	if ( ! did_action( 'wp_print_scripts' ) ) {
  2106 	if ( ! did_action( 'wp_print_scripts' ) ) {
  2033 		/** This action is documented in wp-includes/functions.wp-scripts.php */
  2107 		/** This action is documented in wp-includes/functions.wp-scripts.php */
  2034 		do_action( 'wp_print_scripts' );
  2108 		do_action( 'wp_print_scripts' );
  2035 	}
  2109 	}
  2036 
  2110 
  2037 	global $wp_scripts;
       
  2038 
       
  2039 	if ( ! ( $wp_scripts instanceof WP_Scripts ) ) {
  2111 	if ( ! ( $wp_scripts instanceof WP_Scripts ) ) {
  2040 		return array(); // No need to run if nothing is queued.
  2112 		return array(); // No need to run if nothing is queued.
  2041 	}
  2113 	}
       
  2114 
  2042 	return print_head_scripts();
  2115 	return print_head_scripts();
  2043 }
  2116 }
  2044 
  2117 
  2045 /**
  2118 /**
  2046  * Private, for use in *_footer_scripts hooks
  2119  * Private, for use in *_footer_scripts hooks
  2151 	$wp_styles->reset();
  2224 	$wp_styles->reset();
  2152 	return $wp_styles->done;
  2225 	return $wp_styles->done;
  2153 }
  2226 }
  2154 
  2227 
  2155 /**
  2228 /**
  2156  * Print styles (internal use only)
  2229  * Prints styles (internal use only).
  2157  *
  2230  *
  2158  * @ignore
  2231  * @ignore
  2159  * @since 3.3.0
  2232  * @since 3.3.0
  2160  *
  2233  *
  2161  * @global bool $compress_css
  2234  * @global bool $compress_css
  2198 		echo $wp_styles->print_html;
  2271 		echo $wp_styles->print_html;
  2199 	}
  2272 	}
  2200 }
  2273 }
  2201 
  2274 
  2202 /**
  2275 /**
  2203  * Determine the concatenation and compression settings for scripts and styles.
  2276  * Determines the concatenation and compression settings for scripts and styles.
  2204  *
  2277  *
  2205  * @since 2.8.0
  2278  * @since 2.8.0
  2206  *
  2279  *
  2207  * @global bool $concatenate_scripts
  2280  * @global bool $concatenate_scripts
  2208  * @global bool $compress_scripts
  2281  * @global bool $compress_scripts
  2210  */
  2283  */
  2211 function script_concat_settings() {
  2284 function script_concat_settings() {
  2212 	global $concatenate_scripts, $compress_scripts, $compress_css;
  2285 	global $concatenate_scripts, $compress_scripts, $compress_css;
  2213 
  2286 
  2214 	$compressed_output = ( ini_get( 'zlib.output_compression' ) || 'ob_gzhandler' === ini_get( 'output_handler' ) );
  2287 	$compressed_output = ( ini_get( 'zlib.output_compression' ) || 'ob_gzhandler' === ini_get( 'output_handler' ) );
       
  2288 
       
  2289 	$can_compress_scripts = ! wp_installing() && get_site_option( 'can_compress_scripts' );
  2215 
  2290 
  2216 	if ( ! isset( $concatenate_scripts ) ) {
  2291 	if ( ! isset( $concatenate_scripts ) ) {
  2217 		$concatenate_scripts = defined( 'CONCATENATE_SCRIPTS' ) ? CONCATENATE_SCRIPTS : true;
  2292 		$concatenate_scripts = defined( 'CONCATENATE_SCRIPTS' ) ? CONCATENATE_SCRIPTS : true;
  2218 		if ( ( ! is_admin() && ! did_action( 'login_init' ) ) || ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ) {
  2293 		if ( ( ! is_admin() && ! did_action( 'login_init' ) ) || ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ) {
  2219 			$concatenate_scripts = false;
  2294 			$concatenate_scripts = false;
  2220 		}
  2295 		}
  2221 	}
  2296 	}
  2222 
  2297 
  2223 	if ( ! isset( $compress_scripts ) ) {
  2298 	if ( ! isset( $compress_scripts ) ) {
  2224 		$compress_scripts = defined( 'COMPRESS_SCRIPTS' ) ? COMPRESS_SCRIPTS : true;
  2299 		$compress_scripts = defined( 'COMPRESS_SCRIPTS' ) ? COMPRESS_SCRIPTS : true;
  2225 		if ( $compress_scripts && ( ! get_site_option( 'can_compress_scripts' ) || $compressed_output ) ) {
  2300 		if ( $compress_scripts && ( ! $can_compress_scripts || $compressed_output ) ) {
  2226 			$compress_scripts = false;
  2301 			$compress_scripts = false;
  2227 		}
  2302 		}
  2228 	}
  2303 	}
  2229 
  2304 
  2230 	if ( ! isset( $compress_css ) ) {
  2305 	if ( ! isset( $compress_css ) ) {
  2231 		$compress_css = defined( 'COMPRESS_CSS' ) ? COMPRESS_CSS : true;
  2306 		$compress_css = defined( 'COMPRESS_CSS' ) ? COMPRESS_CSS : true;
  2232 		if ( $compress_css && ( ! get_site_option( 'can_compress_scripts' ) || $compressed_output ) ) {
  2307 		if ( $compress_css && ( ! $can_compress_scripts || $compressed_output ) ) {
  2233 			$compress_css = false;
  2308 			$compress_css = false;
  2234 		}
  2309 		}
  2235 	}
  2310 	}
  2236 }
  2311 }
  2237 
  2312 
  2238 /**
  2313 /**
  2239  * Handles the enqueueing of block scripts and styles that are common to both
  2314  * Handles the enqueueing of block scripts and styles that are common to both
  2240  * the editor and the front-end.
  2315  * the editor and the front-end.
  2241  *
  2316  *
  2242  * @since 5.0.0
  2317  * @since 5.0.0
  2243  *
       
  2244  * @global WP_Screen $current_screen WordPress current screen object.
       
  2245  */
  2318  */
  2246 function wp_common_block_scripts_and_styles() {
  2319 function wp_common_block_scripts_and_styles() {
  2247 	if ( is_admin() && ! wp_should_load_block_editor_scripts_and_styles() ) {
  2320 	if ( is_admin() && ! wp_should_load_block_editor_scripts_and_styles() ) {
  2248 		return;
  2321 		return;
  2249 	}
  2322 	}
  2250 
  2323 
  2251 	wp_enqueue_style( 'wp-block-library' );
  2324 	wp_enqueue_style( 'wp-block-library' );
  2252 
  2325 
  2253 	if ( current_theme_supports( 'wp-block-styles' ) ) {
  2326 	if ( current_theme_supports( 'wp-block-styles' ) ) {
  2254 		wp_enqueue_style( 'wp-block-library-theme' );
  2327 		if ( wp_should_load_separate_core_block_assets() ) {
       
  2328 			$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'css' : 'min.css';
       
  2329 			$files  = glob( __DIR__ . "/blocks/**/theme.$suffix" );
       
  2330 			foreach ( $files as $path ) {
       
  2331 				$block_name = basename( dirname( $path ) );
       
  2332 				if ( is_rtl() && file_exists( __DIR__ . "/blocks/$block_name/theme-rtl.$suffix" ) ) {
       
  2333 					$path = __DIR__ . "/blocks/$block_name/theme-rtl.$suffix";
       
  2334 				}
       
  2335 				wp_add_inline_style( "wp-block-{$block_name}", file_get_contents( $path ) );
       
  2336 			}
       
  2337 		} else {
       
  2338 			wp_enqueue_style( 'wp-block-library-theme' );
       
  2339 		}
  2255 	}
  2340 	}
  2256 
  2341 
  2257 	/**
  2342 	/**
  2258 	 * Fires after enqueuing block assets for both editor and front-end.
  2343 	 * Fires after enqueuing block assets for both editor and front-end.
  2259 	 *
  2344 	 *
  2271  * Enqueues the global styles defined via theme.json.
  2356  * Enqueues the global styles defined via theme.json.
  2272  *
  2357  *
  2273  * @since 5.8.0
  2358  * @since 5.8.0
  2274  */
  2359  */
  2275 function wp_enqueue_global_styles() {
  2360 function wp_enqueue_global_styles() {
  2276 	if ( ! WP_Theme_JSON_Resolver::theme_has_support() ) {
  2361 	$separate_assets  = wp_should_load_separate_core_block_assets();
  2277 		return;
  2362 	$is_block_theme   = wp_is_block_theme();
  2278 	}
  2363 	$is_classic_theme = ! $is_block_theme;
  2279 
       
  2280 	$separate_assets = wp_should_load_separate_core_block_assets();
       
  2281 
  2364 
  2282 	/*
  2365 	/*
  2283 	 * Global styles should be printed in the head when loading all styles combined.
  2366 	 * Global styles should be printed in the head when loading all styles combined.
  2284 	 * The footer should only be used to print global styles for classic themes with separate core assets enabled.
  2367 	 * The footer should only be used to print global styles for classic themes with separate core assets enabled.
  2285 	 *
  2368 	 *
  2286 	 * See https://core.trac.wordpress.org/ticket/53494.
  2369 	 * See https://core.trac.wordpress.org/ticket/53494.
  2287 	 */
  2370 	 */
  2288 	if ( ( ! $separate_assets && doing_action( 'wp_footer' ) ) || ( $separate_assets && doing_action( 'wp_enqueue_scripts' ) ) ) {
  2371 	if (
       
  2372 		( $is_block_theme && doing_action( 'wp_footer' ) ) ||
       
  2373 		( $is_classic_theme && doing_action( 'wp_footer' ) && ! $separate_assets ) ||
       
  2374 		( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) && $separate_assets )
       
  2375 	) {
  2289 		return;
  2376 		return;
  2290 	}
  2377 	}
  2291 
  2378 
  2292 	$can_use_cache = (
  2379 	$stylesheet = wp_get_global_stylesheet();
  2293 		( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) &&
       
  2294 		( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) &&
       
  2295 		( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) &&
       
  2296 		! is_admin()
       
  2297 	);
       
  2298 
       
  2299 	$stylesheet = null;
       
  2300 	if ( $can_use_cache ) {
       
  2301 		$cache = get_transient( 'global_styles' );
       
  2302 		if ( $cache ) {
       
  2303 			$stylesheet = $cache;
       
  2304 		}
       
  2305 	}
       
  2306 
       
  2307 	if ( null === $stylesheet ) {
       
  2308 		$settings   = get_default_block_editor_settings();
       
  2309 		$theme_json = WP_Theme_JSON_Resolver::get_merged_data( $settings );
       
  2310 		$stylesheet = $theme_json->get_stylesheet();
       
  2311 
       
  2312 		if ( $can_use_cache ) {
       
  2313 			set_transient( 'global_styles', $stylesheet, MINUTE_IN_SECONDS );
       
  2314 		}
       
  2315 	}
       
  2316 
  2380 
  2317 	if ( empty( $stylesheet ) ) {
  2381 	if ( empty( $stylesheet ) ) {
  2318 		return;
  2382 		return;
  2319 	}
  2383 	}
  2320 
  2384 
  2322 	wp_add_inline_style( 'global-styles', $stylesheet );
  2386 	wp_add_inline_style( 'global-styles', $stylesheet );
  2323 	wp_enqueue_style( 'global-styles' );
  2387 	wp_enqueue_style( 'global-styles' );
  2324 }
  2388 }
  2325 
  2389 
  2326 /**
  2390 /**
       
  2391  * Renders the SVG filters supplied by theme.json.
       
  2392  *
       
  2393  * Note that this doesn't render the per-block user-defined
       
  2394  * filters which are handled by wp_render_duotone_support,
       
  2395  * but it should be rendered before the filtered content
       
  2396  * in the body to satisfy Safari's rendering quirks.
       
  2397  *
       
  2398  * @since 5.9.1
       
  2399  */
       
  2400 function wp_global_styles_render_svg_filters() {
       
  2401 	/*
       
  2402 	 * When calling via the in_admin_header action, we only want to render the
       
  2403 	 * SVGs on block editor pages.
       
  2404 	 */
       
  2405 	if (
       
  2406 		is_admin() &&
       
  2407 		! get_current_screen()->is_block_editor()
       
  2408 	) {
       
  2409 		return;
       
  2410 	}
       
  2411 
       
  2412 	$filters = wp_get_global_styles_svg_filters();
       
  2413 	if ( ! empty( $filters ) ) {
       
  2414 		echo $filters;
       
  2415 	}
       
  2416 }
       
  2417 
       
  2418 /**
  2327  * Checks if the editor scripts and styles for all registered block types
  2419  * Checks if the editor scripts and styles for all registered block types
  2328  * should be enqueued on the current screen.
  2420  * should be enqueued on the current screen.
  2329  *
  2421  *
  2330  * @since 5.6.0
  2422  * @since 5.6.0
       
  2423  *
       
  2424  * @global WP_Screen $current_screen WordPress current screen object.
  2331  *
  2425  *
  2332  * @return bool Whether scripts and styles should be enqueued.
  2426  * @return bool Whether scripts and styles should be enqueued.
  2333  */
  2427  */
  2334 function wp_should_load_block_editor_scripts_and_styles() {
  2428 function wp_should_load_block_editor_scripts_and_styles() {
  2335 	global $current_screen;
  2429 	global $current_screen;
  2430 
  2524 
  2431 /**
  2525 /**
  2432  * Function responsible for enqueuing the styles required for block styles functionality on the editor and on the frontend.
  2526  * Function responsible for enqueuing the styles required for block styles functionality on the editor and on the frontend.
  2433  *
  2527  *
  2434  * @since 5.3.0
  2528  * @since 5.3.0
       
  2529  *
       
  2530  * @global WP_Styles $wp_styles
  2435  */
  2531  */
  2436 function enqueue_block_styles_assets() {
  2532 function enqueue_block_styles_assets() {
       
  2533 	global $wp_styles;
       
  2534 
  2437 	$block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered();
  2535 	$block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered();
  2438 
  2536 
  2439 	foreach ( $block_styles as $block_name => $styles ) {
  2537 	foreach ( $block_styles as $block_name => $styles ) {
  2440 		foreach ( $styles as $style_properties ) {
  2538 		foreach ( $styles as $style_properties ) {
  2441 			if ( isset( $style_properties['style_handle'] ) ) {
  2539 			if ( isset( $style_properties['style_handle'] ) ) {
  2442 
  2540 
  2443 				// If the site loads separate styles per-block, enqueue the stylesheet on render.
  2541 				// If the site loads separate styles per-block, enqueue the stylesheet on render.
  2444 				if ( wp_should_load_separate_core_block_assets() ) {
  2542 				if ( wp_should_load_separate_core_block_assets() ) {
  2445 					add_filter(
  2543 					add_filter(
  2446 						'render_block',
  2544 						'render_block',
  2447 						function( $html, $block ) use ( $style_properties ) {
  2545 						function( $html, $block ) use ( $block_name, $style_properties ) {
  2448 							wp_enqueue_style( $style_properties['style_handle'] );
  2546 							if ( $block['blockName'] === $block_name ) {
       
  2547 								wp_enqueue_style( $style_properties['style_handle'] );
       
  2548 							}
  2449 							return $html;
  2549 							return $html;
  2450 						}
  2550 						},
       
  2551 						10,
       
  2552 						2
  2451 					);
  2553 					);
  2452 				} else {
  2554 				} else {
  2453 					wp_enqueue_style( $style_properties['style_handle'] );
  2555 					wp_enqueue_style( $style_properties['style_handle'] );
  2454 				}
  2556 				}
  2455 			}
  2557 			}
  2459 				$handle = 'wp-block-library';
  2561 				$handle = 'wp-block-library';
  2460 
  2562 
  2461 				// If the site loads separate styles per-block, check if the block has a stylesheet registered.
  2563 				// If the site loads separate styles per-block, check if the block has a stylesheet registered.
  2462 				if ( wp_should_load_separate_core_block_assets() ) {
  2564 				if ( wp_should_load_separate_core_block_assets() ) {
  2463 					$block_stylesheet_handle = generate_block_asset_handle( $block_name, 'style' );
  2565 					$block_stylesheet_handle = generate_block_asset_handle( $block_name, 'style' );
  2464 					global $wp_styles;
  2566 
  2465 					if ( isset( $wp_styles->registered[ $block_stylesheet_handle ] ) ) {
  2567 					if ( isset( $wp_styles->registered[ $block_stylesheet_handle ] ) ) {
  2466 						$handle = $block_stylesheet_handle;
  2568 						$handle = $block_stylesheet_handle;
  2467 					}
  2569 					}
  2468 				}
  2570 				}
  2469 
  2571 
  2607  * Automatically injects type attribute if needed.
  2709  * Automatically injects type attribute if needed.
  2608  *
  2710  *
  2609  * @since 5.7.0
  2711  * @since 5.7.0
  2610  *
  2712  *
  2611  * @param string $javascript Inline JavaScript code.
  2713  * @param string $javascript Inline JavaScript code.
  2612  * @param array  $attributes  Optional. Key-value pairs representing `<script>` tag attributes.
  2714  * @param array  $attributes Optional. Key-value pairs representing `<script>` tag attributes.
  2613  * @return string String containing inline JavaScript code wrapped around `<script>` tag.
  2715  * @return string String containing inline JavaScript code wrapped around `<script>` tag.
  2614  */
  2716  */
  2615 function wp_get_inline_script_tag( $javascript, $attributes = array() ) {
  2717 function wp_get_inline_script_tag( $javascript, $attributes = array() ) {
  2616 	if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) {
  2718 	if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) {
  2617 		$attributes['type'] = 'text/javascript';
  2719 		$attributes['type'] = 'text/javascript';
  2619 	/**
  2721 	/**
  2620 	 * Filters attributes to be added to a script tag.
  2722 	 * Filters attributes to be added to a script tag.
  2621 	 *
  2723 	 *
  2622 	 * @since 5.7.0
  2724 	 * @since 5.7.0
  2623 	 *
  2725 	 *
  2624 	 * @param array $attributes Key-value pairs representing `<script>` tag attributes.
  2726 	 * @param array  $attributes Key-value pairs representing `<script>` tag attributes.
  2625 	 *                          Only the attribute name is added to the `<script>` tag for
  2727 	 *                           Only the attribute name is added to the `<script>` tag for
  2626 	 *                          entries with a boolean value, and that are true.
  2728 	 *                           entries with a boolean value, and that are true.
       
  2729 	 * @param string $javascript Inline JavaScript code.
  2627 	 */
  2730 	 */
  2628 	$attributes = apply_filters( 'wp_inline_script_attributes', $attributes, $javascript );
  2731 	$attributes = apply_filters( 'wp_inline_script_attributes', $attributes, $javascript );
  2629 
  2732 
  2630 	$javascript = "\n" . trim( $javascript, "\n\r " ) . "\n";
  2733 	$javascript = "\n" . trim( $javascript, "\n\r " ) . "\n";
  2631 
  2734 
  2677 	// Build an array of styles that have a path defined.
  2780 	// Build an array of styles that have a path defined.
  2678 	foreach ( $wp_styles->queue as $handle ) {
  2781 	foreach ( $wp_styles->queue as $handle ) {
  2679 		if ( wp_styles()->get_data( $handle, 'path' ) && file_exists( $wp_styles->registered[ $handle ]->extra['path'] ) ) {
  2782 		if ( wp_styles()->get_data( $handle, 'path' ) && file_exists( $wp_styles->registered[ $handle ]->extra['path'] ) ) {
  2680 			$styles[] = array(
  2783 			$styles[] = array(
  2681 				'handle' => $handle,
  2784 				'handle' => $handle,
       
  2785 				'src'    => $wp_styles->registered[ $handle ]->src,
  2682 				'path'   => $wp_styles->registered[ $handle ]->extra['path'],
  2786 				'path'   => $wp_styles->registered[ $handle ]->extra['path'],
  2683 				'size'   => filesize( $wp_styles->registered[ $handle ]->extra['path'] ),
  2787 				'size'   => filesize( $wp_styles->registered[ $handle ]->extra['path'] ),
  2684 			);
  2788 			);
  2685 		}
  2789 		}
  2686 	}
  2790 	}
  2687 
  2791 
  2688 	if ( ! empty( $styles ) ) {
  2792 	if ( ! empty( $styles ) ) {
  2689 		// Reorder styles array based on size.
  2793 		// Reorder styles array based on size.
  2690 		usort(
  2794 		usort(
  2691 			$styles,
  2795 			$styles,
  2692 			function( $a, $b ) {
  2796 			static function( $a, $b ) {
  2693 				return ( $a['size'] <= $b['size'] ) ? -1 : 1;
  2797 				return ( $a['size'] <= $b['size'] ) ? -1 : 1;
  2694 			}
  2798 			}
  2695 		);
  2799 		);
  2696 
  2800 
  2697 		/*
  2801 		/*
  2711 			}
  2815 			}
  2712 
  2816 
  2713 			// Get the styles if we don't already have them.
  2817 			// Get the styles if we don't already have them.
  2714 			$style['css'] = file_get_contents( $style['path'] );
  2818 			$style['css'] = file_get_contents( $style['path'] );
  2715 
  2819 
       
  2820 			// Check if the style contains relative URLs that need to be modified.
       
  2821 			// URLs relative to the stylesheet's path should be converted to relative to the site's root.
       
  2822 			$style['css'] = _wp_normalize_relative_css_links( $style['css'], $style['src'] );
       
  2823 
  2716 			// Set `src` to `false` and add styles inline.
  2824 			// Set `src` to `false` and add styles inline.
  2717 			$wp_styles->registered[ $style['handle'] ]->src = false;
  2825 			$wp_styles->registered[ $style['handle'] ]->src = false;
  2718 			if ( empty( $wp_styles->registered[ $style['handle'] ]->extra['after'] ) ) {
  2826 			if ( empty( $wp_styles->registered[ $style['handle'] ]->extra['after'] ) ) {
  2719 				$wp_styles->registered[ $style['handle'] ]->extra['after'] = array();
  2827 				$wp_styles->registered[ $style['handle'] ]->extra['after'] = array();
  2720 			}
  2828 			}
  2725 		}
  2833 		}
  2726 	}
  2834 	}
  2727 }
  2835 }
  2728 
  2836 
  2729 /**
  2837 /**
  2730  * Inject the block editor assets that need to be loaded into the editor's iframe as an inline script.
  2838  * Makes URLs relative to the WordPress installation.
  2731  *
  2839  *
  2732  * @since 5.8.0
  2840  * @since 5.9.0
  2733  */
  2841  * @access private
  2734 function wp_add_iframed_editor_assets_html() {
  2842  *
  2735 	if ( ! wp_should_load_block_editor_scripts_and_styles() ) {
  2843  * @param string $css            The CSS to make URLs relative to the WordPress installation.
       
  2844  * @param string $stylesheet_url The URL to the stylesheet.
       
  2845  *
       
  2846  * @return string The CSS with URLs made relative to the WordPress installation.
       
  2847  */
       
  2848 function _wp_normalize_relative_css_links( $css, $stylesheet_url ) {
       
  2849 	$has_src_results = preg_match_all( '#url\s*\(\s*[\'"]?\s*([^\'"\)]+)#', $css, $src_results );
       
  2850 	if ( $has_src_results ) {
       
  2851 		// Loop through the URLs to find relative ones.
       
  2852 		foreach ( $src_results[1] as $src_index => $src_result ) {
       
  2853 			// Skip if this is an absolute URL.
       
  2854 			if ( 0 === strpos( $src_result, 'http' ) || 0 === strpos( $src_result, '//' ) ) {
       
  2855 				continue;
       
  2856 			}
       
  2857 
       
  2858 			// Skip if the URL is an HTML ID.
       
  2859 			if ( str_starts_with( $src_result, '#' ) ) {
       
  2860 				continue;
       
  2861 			}
       
  2862 
       
  2863 			// Skip if the URL is a data URI.
       
  2864 			if ( str_starts_with( $src_result, 'data:' ) ) {
       
  2865 				continue;
       
  2866 			}
       
  2867 
       
  2868 			// Build the absolute URL.
       
  2869 			$absolute_url = dirname( $stylesheet_url ) . '/' . $src_result;
       
  2870 			$absolute_url = str_replace( '/./', '/', $absolute_url );
       
  2871 			// Convert to URL related to the site root.
       
  2872 			$relative_url = wp_make_link_relative( $absolute_url );
       
  2873 
       
  2874 			// Replace the URL in the CSS.
       
  2875 			$css = str_replace(
       
  2876 				$src_results[0][ $src_index ],
       
  2877 				str_replace( $src_result, $relative_url, $src_results[0][ $src_index ] ),
       
  2878 				$css
       
  2879 			);
       
  2880 		}
       
  2881 	}
       
  2882 
       
  2883 	return $css;
       
  2884 }
       
  2885 
       
  2886 /**
       
  2887  * Function that enqueues the CSS Custom Properties coming from theme.json.
       
  2888  *
       
  2889  * @since 5.9.0
       
  2890  */
       
  2891 function wp_enqueue_global_styles_css_custom_properties() {
       
  2892 	wp_register_style( 'global-styles-css-custom-properties', false, array(), true, true );
       
  2893 	wp_add_inline_style( 'global-styles-css-custom-properties', wp_get_global_stylesheet( array( 'variables' ) ) );
       
  2894 	wp_enqueue_style( 'global-styles-css-custom-properties' );
       
  2895 }
       
  2896 
       
  2897 /**
       
  2898  * This function takes care of adding inline styles
       
  2899  * in the proper place, depending on the theme in use.
       
  2900  *
       
  2901  * @since 5.9.1
       
  2902  *
       
  2903  * For block themes, it's loaded in the head.
       
  2904  * For classic ones, it's loaded in the body
       
  2905  * because the wp_head action happens before
       
  2906  * the render_block.
       
  2907  *
       
  2908  * @link https://core.trac.wordpress.org/ticket/53494.
       
  2909  *
       
  2910  * @param string $style String containing the CSS styles to be added.
       
  2911  */
       
  2912 function wp_enqueue_block_support_styles( $style ) {
       
  2913 	$action_hook_name = 'wp_footer';
       
  2914 	if ( wp_is_block_theme() ) {
       
  2915 		$action_hook_name = 'wp_head';
       
  2916 	}
       
  2917 	add_action(
       
  2918 		$action_hook_name,
       
  2919 		static function () use ( $style ) {
       
  2920 			echo "<style>$style</style>\n";
       
  2921 		}
       
  2922 	);
       
  2923 }
       
  2924 
       
  2925 /**
       
  2926  * Enqueues a stylesheet for a specific block.
       
  2927  *
       
  2928  * If the theme has opted-in to separate-styles loading,
       
  2929  * then the stylesheet will be enqueued on-render,
       
  2930  * otherwise when the block inits.
       
  2931  *
       
  2932  * @since 5.9.0
       
  2933  *
       
  2934  * @param string $block_name The block-name, including namespace.
       
  2935  * @param array  $args       An array of arguments [handle,src,deps,ver,media].
       
  2936  */
       
  2937 function wp_enqueue_block_style( $block_name, $args ) {
       
  2938 	$args = wp_parse_args(
       
  2939 		$args,
       
  2940 		array(
       
  2941 			'handle' => '',
       
  2942 			'src'    => '',
       
  2943 			'deps'   => array(),
       
  2944 			'ver'    => false,
       
  2945 			'media'  => 'all',
       
  2946 		)
       
  2947 	);
       
  2948 
       
  2949 	/**
       
  2950 	 * Callback function to register and enqueue styles.
       
  2951 	 *
       
  2952 	 * @param string $content When the callback is used for the render_block filter,
       
  2953 	 *                        the content needs to be returned so the function parameter
       
  2954 	 *                        is to ensure the content exists.
       
  2955 	 * @return string Block content.
       
  2956 	 */
       
  2957 	$callback = static function( $content ) use ( $args ) {
       
  2958 		// Register the stylesheet.
       
  2959 		if ( ! empty( $args['src'] ) ) {
       
  2960 			wp_register_style( $args['handle'], $args['src'], $args['deps'], $args['ver'], $args['media'] );
       
  2961 		}
       
  2962 
       
  2963 		// Add `path` data if provided.
       
  2964 		if ( isset( $args['path'] ) ) {
       
  2965 			wp_style_add_data( $args['handle'], 'path', $args['path'] );
       
  2966 
       
  2967 			// Get the RTL file path.
       
  2968 			$rtl_file_path = str_replace( '.css', '-rtl.css', $args['path'] );
       
  2969 
       
  2970 			// Add RTL stylesheet.
       
  2971 			if ( file_exists( $rtl_file_path ) ) {
       
  2972 				wp_style_add_data( $args['handle'], 'rtl', 'replace' );
       
  2973 
       
  2974 				if ( is_rtl() ) {
       
  2975 					wp_style_add_data( $args['handle'], 'path', $rtl_file_path );
       
  2976 				}
       
  2977 			}
       
  2978 		}
       
  2979 
       
  2980 		// Enqueue the stylesheet.
       
  2981 		wp_enqueue_style( $args['handle'] );
       
  2982 
       
  2983 		return $content;
       
  2984 	};
       
  2985 
       
  2986 	$hook = did_action( 'wp_enqueue_scripts' ) ? 'wp_footer' : 'wp_enqueue_scripts';
       
  2987 	if ( wp_should_load_separate_core_block_assets() ) {
       
  2988 		/**
       
  2989 		 * Callback function to register and enqueue styles.
       
  2990 		 *
       
  2991 		 * @param string $content The block content.
       
  2992 		 * @param array  $block   The full block, including name and attributes.
       
  2993 		 * @return string Block content.
       
  2994 		 */
       
  2995 		$callback_separate = static function( $content, $block ) use ( $block_name, $callback ) {
       
  2996 			if ( ! empty( $block['blockName'] ) && $block_name === $block['blockName'] ) {
       
  2997 				return $callback( $content );
       
  2998 			}
       
  2999 			return $content;
       
  3000 		};
       
  3001 
       
  3002 		/*
       
  3003 		 * The filter's callback here is an anonymous function because
       
  3004 		 * using a named function in this case is not possible.
       
  3005 		 *
       
  3006 		 * The function cannot be unhooked, however, users are still able
       
  3007 		 * to dequeue the stylesheets registered/enqueued by the callback
       
  3008 		 * which is why in this case, using an anonymous function
       
  3009 		 * was deemed acceptable.
       
  3010 		 */
       
  3011 		add_filter( 'render_block', $callback_separate, 10, 2 );
  2736 		return;
  3012 		return;
  2737 	}
  3013 	}
  2738 
  3014 
  2739 	$script_handles = array();
  3015 	/*
  2740 	$style_handles  = array(
  3016 	 * The filter's callback here is an anonymous function because
  2741 		'wp-block-editor',
  3017 	 * using a named function in this case is not possible.
  2742 		'wp-block-library',
  3018 	 *
  2743 		'wp-block-library-theme',
  3019 	 * The function cannot be unhooked, however, users are still able
  2744 		'wp-edit-blocks',
  3020 	 * to dequeue the stylesheets registered/enqueued by the callback
  2745 	);
  3021 	 * which is why in this case, using an anonymous function
  2746 
  3022 	 * was deemed acceptable.
  2747 	$block_registry = WP_Block_Type_Registry::get_instance();
  3023 	 */
  2748 
  3024 	add_filter( $hook, $callback );
  2749 	foreach ( $block_registry->get_all_registered() as $block_type ) {
  3025 
  2750 		if ( ! empty( $block_type->style ) ) {
  3026 	// Enqueue assets in the editor.
  2751 			$style_handles[] = $block_type->style;
  3027 	add_action( 'enqueue_block_assets', $callback );
  2752 		}
  3028 }
  2753 
  3029 
  2754 		if ( ! empty( $block_type->editor_style ) ) {
  3030 /**
  2755 			$style_handles[] = $block_type->editor_style;
  3031  * Runs the theme.json webfonts handler.
  2756 		}
  3032  *
  2757 
  3033  * Using `WP_Theme_JSON_Resolver`, it gets the fonts defined
  2758 		if ( ! empty( $block_type->script ) ) {
  3034  * in the `theme.json` for the current selection and style
  2759 			$script_handles[] = $block_type->script;
  3035  * variations, validates the font-face properties, generates
  2760 		}
  3036  * the '@font-face' style declarations, and then enqueues the
  2761 	}
  3037  * styles for both the editor and front-end.
  2762 
  3038  *
  2763 	$style_handles = array_unique( $style_handles );
  3039  * Design Notes:
  2764 	$done          = wp_styles()->done;
  3040  * This is not a public API, but rather an internal handler.
  2765 
  3041  * A future public Webfonts API will replace this stopgap code.
  2766 	ob_start();
  3042  *
  2767 
  3043  * This code design is intentional.
  2768 	wp_styles()->done = array();
  3044  *    a. It hides the inner-workings.
  2769 	wp_styles()->do_items( $style_handles );
  3045  *    b. It does not expose API ins or outs for consumption.
  2770 	wp_styles()->done = $done;
  3046  *    c. It only works with a theme's `theme.json`.
  2771 
  3047  *
  2772 	$styles = ob_get_clean();
  3048  * Why?
  2773 
  3049  *    a. To avoid backwards-compatibility issues when
  2774 	$script_handles = array_unique( $script_handles );
  3050  *       the Webfonts API is introduced in Core.
  2775 	$done           = wp_scripts()->done;
  3051  *    b. To make `fontFace` declarations in `theme.json` work.
  2776 
  3052  *
  2777 	ob_start();
  3053  * @link  https://github.com/WordPress/gutenberg/issues/40472
  2778 
  3054  *
  2779 	wp_scripts()->done = array();
  3055  * @since 6.0.0
  2780 	wp_scripts()->do_items( $script_handles );
  3056  * @access private
  2781 	wp_scripts()->done = $done;
  3057  */
  2782 
  3058 function _wp_theme_json_webfonts_handler() {
  2783 	$scripts = ob_get_clean();
  3059 	// Block themes are unavailable during installation.
  2784 
  3060 	if ( wp_installing() ) {
  2785 	$editor_assets = wp_json_encode(
  3061 		return;
  2786 		array(
  3062 	}
  2787 			'styles'  => $styles,
  3063 
  2788 			'scripts' => $scripts,
  3064 	// Webfonts to be processed.
  2789 		)
  3065 	$registered_webfonts = array();
  2790 	);
  3066 
  2791 
  3067 	/**
  2792 	echo "<script>window.__editorAssets = $editor_assets</script>";
  3068 	 * Gets the webfonts from theme.json.
  2793 }
  3069 	 *
       
  3070 	 * @since 6.0.0
       
  3071 	 *
       
  3072 	 * @return array Array of defined webfonts.
       
  3073 	 */
       
  3074 	$fn_get_webfonts_from_theme_json = static function() {
       
  3075 		// Get settings from theme.json.
       
  3076 		$settings = WP_Theme_JSON_Resolver::get_merged_data()->get_settings();
       
  3077 
       
  3078 		// If in the editor, add webfonts defined in variations.
       
  3079 		if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) {
       
  3080 			$variations = WP_Theme_JSON_Resolver::get_style_variations();
       
  3081 			foreach ( $variations as $variation ) {
       
  3082 				// Skip if fontFamilies are not defined in the variation.
       
  3083 				if ( empty( $variation['settings']['typography']['fontFamilies'] ) ) {
       
  3084 					continue;
       
  3085 				}
       
  3086 
       
  3087 				// Initialize the array structure.
       
  3088 				if ( empty( $settings['typography'] ) ) {
       
  3089 					$settings['typography'] = array();
       
  3090 				}
       
  3091 				if ( empty( $settings['typography']['fontFamilies'] ) ) {
       
  3092 					$settings['typography']['fontFamilies'] = array();
       
  3093 				}
       
  3094 				if ( empty( $settings['typography']['fontFamilies']['theme'] ) ) {
       
  3095 					$settings['typography']['fontFamilies']['theme'] = array();
       
  3096 				}
       
  3097 
       
  3098 				// Combine variations with settings. Remove duplicates.
       
  3099 				$settings['typography']['fontFamilies']['theme'] = array_merge( $settings['typography']['fontFamilies']['theme'], $variation['settings']['typography']['fontFamilies']['theme'] );
       
  3100 				$settings['typography']['fontFamilies']          = array_unique( $settings['typography']['fontFamilies'] );
       
  3101 			}
       
  3102 		}
       
  3103 
       
  3104 		// Bail out early if there are no settings for webfonts.
       
  3105 		if ( empty( $settings['typography']['fontFamilies'] ) ) {
       
  3106 			return array();
       
  3107 		}
       
  3108 
       
  3109 		$webfonts = array();
       
  3110 
       
  3111 		// Look for fontFamilies.
       
  3112 		foreach ( $settings['typography']['fontFamilies'] as $font_families ) {
       
  3113 			foreach ( $font_families as $font_family ) {
       
  3114 
       
  3115 				// Skip if fontFace is not defined.
       
  3116 				if ( empty( $font_family['fontFace'] ) ) {
       
  3117 					continue;
       
  3118 				}
       
  3119 
       
  3120 				// Skip if fontFace is not an array of webfonts.
       
  3121 				if ( ! is_array( $font_family['fontFace'] ) ) {
       
  3122 					continue;
       
  3123 				}
       
  3124 
       
  3125 				$webfonts = array_merge( $webfonts, $font_family['fontFace'] );
       
  3126 			}
       
  3127 		}
       
  3128 
       
  3129 		return $webfonts;
       
  3130 	};
       
  3131 
       
  3132 	/**
       
  3133 	 * Transforms each 'src' into an URI by replacing 'file:./'
       
  3134 	 * placeholder from theme.json.
       
  3135 	 *
       
  3136 	 * The absolute path to the webfont file(s) cannot be defined in
       
  3137 	 * theme.json. `file:./` is the placeholder which is replaced by
       
  3138 	 * the theme's URL path to the theme's root.
       
  3139 	 *
       
  3140 	 * @since 6.0.0
       
  3141 	 *
       
  3142 	 * @param array $src Webfont file(s) `src`.
       
  3143 	 * @return array Webfont's `src` in URI.
       
  3144 	 */
       
  3145 	$fn_transform_src_into_uri = static function( array $src ) {
       
  3146 		foreach ( $src as $key => $url ) {
       
  3147 			// Tweak the URL to be relative to the theme root.
       
  3148 			if ( ! str_starts_with( $url, 'file:./' ) ) {
       
  3149 				continue;
       
  3150 			}
       
  3151 
       
  3152 			$src[ $key ] = get_theme_file_uri( str_replace( 'file:./', '', $url ) );
       
  3153 		}
       
  3154 
       
  3155 		return $src;
       
  3156 	};
       
  3157 
       
  3158 	/**
       
  3159 	 * Converts the font-face properties (i.e. keys) into kebab-case.
       
  3160 	 *
       
  3161 	 * @since 6.0.0
       
  3162 	 *
       
  3163 	 * @param array $font_face Font face to convert.
       
  3164 	 * @return array Font faces with each property in kebab-case format.
       
  3165 	 */
       
  3166 	$fn_convert_keys_to_kebab_case = static function( array $font_face ) {
       
  3167 		foreach ( $font_face as $property => $value ) {
       
  3168 			$kebab_case               = _wp_to_kebab_case( $property );
       
  3169 			$font_face[ $kebab_case ] = $value;
       
  3170 			if ( $kebab_case !== $property ) {
       
  3171 				unset( $font_face[ $property ] );
       
  3172 			}
       
  3173 		}
       
  3174 
       
  3175 		return $font_face;
       
  3176 	};
       
  3177 
       
  3178 	/**
       
  3179 	 * Validates a webfont.
       
  3180 	 *
       
  3181 	 * @since 6.0.0
       
  3182 	 *
       
  3183 	 * @param array $webfont The webfont arguments.
       
  3184 	 * @return array|false The validated webfont arguments, or false if the webfont is invalid.
       
  3185 	 */
       
  3186 	$fn_validate_webfont = static function( $webfont ) {
       
  3187 		$webfont = wp_parse_args(
       
  3188 			$webfont,
       
  3189 			array(
       
  3190 				'font-family'  => '',
       
  3191 				'font-style'   => 'normal',
       
  3192 				'font-weight'  => '400',
       
  3193 				'font-display' => 'fallback',
       
  3194 				'src'          => array(),
       
  3195 			)
       
  3196 		);
       
  3197 
       
  3198 		// Check the font-family.
       
  3199 		if ( empty( $webfont['font-family'] ) || ! is_string( $webfont['font-family'] ) ) {
       
  3200 			trigger_error( __( 'Webfont font family must be a non-empty string.' ) );
       
  3201 
       
  3202 			return false;
       
  3203 		}
       
  3204 
       
  3205 		// Check that the `src` property is defined and a valid type.
       
  3206 		if ( empty( $webfont['src'] ) || ( ! is_string( $webfont['src'] ) && ! is_array( $webfont['src'] ) ) ) {
       
  3207 			trigger_error( __( 'Webfont src must be a non-empty string or an array of strings.' ) );
       
  3208 
       
  3209 			return false;
       
  3210 		}
       
  3211 
       
  3212 		// Validate the `src` property.
       
  3213 		foreach ( (array) $webfont['src'] as $src ) {
       
  3214 			if ( ! is_string( $src ) || '' === trim( $src ) ) {
       
  3215 				trigger_error( __( 'Each webfont src must be a non-empty string.' ) );
       
  3216 
       
  3217 				return false;
       
  3218 			}
       
  3219 		}
       
  3220 
       
  3221 		// Check the font-weight.
       
  3222 		if ( ! is_string( $webfont['font-weight'] ) && ! is_int( $webfont['font-weight'] ) ) {
       
  3223 			trigger_error( __( 'Webfont font weight must be a properly formatted string or integer.' ) );
       
  3224 
       
  3225 			return false;
       
  3226 		}
       
  3227 
       
  3228 		// Check the font-display.
       
  3229 		if ( ! in_array( $webfont['font-display'], array( 'auto', 'block', 'fallback', 'swap' ), true ) ) {
       
  3230 			$webfont['font-display'] = 'fallback';
       
  3231 		}
       
  3232 
       
  3233 		$valid_props = array(
       
  3234 			'ascend-override',
       
  3235 			'descend-override',
       
  3236 			'font-display',
       
  3237 			'font-family',
       
  3238 			'font-stretch',
       
  3239 			'font-style',
       
  3240 			'font-weight',
       
  3241 			'font-variant',
       
  3242 			'font-feature-settings',
       
  3243 			'font-variation-settings',
       
  3244 			'line-gap-override',
       
  3245 			'size-adjust',
       
  3246 			'src',
       
  3247 			'unicode-range',
       
  3248 		);
       
  3249 
       
  3250 		foreach ( $webfont as $prop => $value ) {
       
  3251 			if ( ! in_array( $prop, $valid_props, true ) ) {
       
  3252 				unset( $webfont[ $prop ] );
       
  3253 			}
       
  3254 		}
       
  3255 
       
  3256 		return $webfont;
       
  3257 	};
       
  3258 
       
  3259 	/**
       
  3260 	 * Registers webfonts declared in theme.json.
       
  3261 	 *
       
  3262 	 * @since 6.0.0
       
  3263 	 *
       
  3264 	 * @uses $registered_webfonts To access and update the registered webfonts registry (passed by reference).
       
  3265 	 * @uses $fn_get_webfonts_from_theme_json To run the function that gets the webfonts from theme.json.
       
  3266 	 * @uses $fn_convert_keys_to_kebab_case To run the function that converts keys into kebab-case.
       
  3267 	 * @uses $fn_validate_webfont To run the function that validates each font-face (webfont) from theme.json.
       
  3268 	 */
       
  3269 	$fn_register_webfonts = static function() use ( &$registered_webfonts, $fn_get_webfonts_from_theme_json, $fn_convert_keys_to_kebab_case, $fn_validate_webfont, $fn_transform_src_into_uri ) {
       
  3270 		$registered_webfonts = array();
       
  3271 
       
  3272 		foreach ( $fn_get_webfonts_from_theme_json() as $webfont ) {
       
  3273 			if ( ! is_array( $webfont ) ) {
       
  3274 				continue;
       
  3275 			}
       
  3276 
       
  3277 			$webfont = $fn_convert_keys_to_kebab_case( $webfont );
       
  3278 
       
  3279 			$webfont = $fn_validate_webfont( $webfont );
       
  3280 
       
  3281 			$webfont['src'] = $fn_transform_src_into_uri( (array) $webfont['src'] );
       
  3282 
       
  3283 			// Skip if not valid.
       
  3284 			if ( empty( $webfont ) ) {
       
  3285 				continue;
       
  3286 			}
       
  3287 
       
  3288 			$registered_webfonts[] = $webfont;
       
  3289 		}
       
  3290 	};
       
  3291 
       
  3292 	/**
       
  3293 	 * Orders 'src' items to optimize for browser support.
       
  3294 	 *
       
  3295 	 * @since 6.0.0
       
  3296 	 *
       
  3297 	 * @param array $webfont Webfont to process.
       
  3298 	 * @return array Ordered `src` items.
       
  3299 	 */
       
  3300 	$fn_order_src = static function( array $webfont ) {
       
  3301 		$src         = array();
       
  3302 		$src_ordered = array();
       
  3303 
       
  3304 		foreach ( $webfont['src'] as $url ) {
       
  3305 			// Add data URIs first.
       
  3306 			if ( str_starts_with( trim( $url ), 'data:' ) ) {
       
  3307 				$src_ordered[] = array(
       
  3308 					'url'    => $url,
       
  3309 					'format' => 'data',
       
  3310 				);
       
  3311 				continue;
       
  3312 			}
       
  3313 			$format         = pathinfo( $url, PATHINFO_EXTENSION );
       
  3314 			$src[ $format ] = $url;
       
  3315 		}
       
  3316 
       
  3317 		// Add woff2.
       
  3318 		if ( ! empty( $src['woff2'] ) ) {
       
  3319 			$src_ordered[] = array(
       
  3320 				'url'    => sanitize_url( $src['woff2'] ),
       
  3321 				'format' => 'woff2',
       
  3322 			);
       
  3323 		}
       
  3324 
       
  3325 		// Add woff.
       
  3326 		if ( ! empty( $src['woff'] ) ) {
       
  3327 			$src_ordered[] = array(
       
  3328 				'url'    => sanitize_url( $src['woff'] ),
       
  3329 				'format' => 'woff',
       
  3330 			);
       
  3331 		}
       
  3332 
       
  3333 		// Add ttf.
       
  3334 		if ( ! empty( $src['ttf'] ) ) {
       
  3335 			$src_ordered[] = array(
       
  3336 				'url'    => sanitize_url( $src['ttf'] ),
       
  3337 				'format' => 'truetype',
       
  3338 			);
       
  3339 		}
       
  3340 
       
  3341 		// Add eot.
       
  3342 		if ( ! empty( $src['eot'] ) ) {
       
  3343 			$src_ordered[] = array(
       
  3344 				'url'    => sanitize_url( $src['eot'] ),
       
  3345 				'format' => 'embedded-opentype',
       
  3346 			);
       
  3347 		}
       
  3348 
       
  3349 		// Add otf.
       
  3350 		if ( ! empty( $src['otf'] ) ) {
       
  3351 			$src_ordered[] = array(
       
  3352 				'url'    => sanitize_url( $src['otf'] ),
       
  3353 				'format' => 'opentype',
       
  3354 			);
       
  3355 		}
       
  3356 		$webfont['src'] = $src_ordered;
       
  3357 
       
  3358 		return $webfont;
       
  3359 	};
       
  3360 
       
  3361 	/**
       
  3362 	 * Compiles the 'src' into valid CSS.
       
  3363 	 *
       
  3364 	 * @since 6.0.0
       
  3365 	 *
       
  3366 	 * @param string $font_family Font family.
       
  3367 	 * @param array  $value       Value to process.
       
  3368 	 * @return string The CSS.
       
  3369 	 */
       
  3370 	$fn_compile_src = static function( $font_family, array $value ) {
       
  3371 		$src = "local($font_family)";
       
  3372 
       
  3373 		foreach ( $value as $item ) {
       
  3374 
       
  3375 			if (
       
  3376 				str_starts_with( $item['url'], site_url() ) ||
       
  3377 				str_starts_with( $item['url'], home_url() )
       
  3378 			) {
       
  3379 				$item['url'] = wp_make_link_relative( $item['url'] );
       
  3380 			}
       
  3381 
       
  3382 			$src .= ( 'data' === $item['format'] )
       
  3383 				? ", url({$item['url']})"
       
  3384 				: ", url('{$item['url']}') format('{$item['format']}')";
       
  3385 		}
       
  3386 
       
  3387 		return $src;
       
  3388 	};
       
  3389 
       
  3390 	/**
       
  3391 	 * Compiles the font variation settings.
       
  3392 	 *
       
  3393 	 * @since 6.0.0
       
  3394 	 *
       
  3395 	 * @param array $font_variation_settings Array of font variation settings.
       
  3396 	 * @return string The CSS.
       
  3397 	 */
       
  3398 	$fn_compile_variations = static function( array $font_variation_settings ) {
       
  3399 		$variations = '';
       
  3400 
       
  3401 		foreach ( $font_variation_settings as $key => $value ) {
       
  3402 			$variations .= "$key $value";
       
  3403 		}
       
  3404 
       
  3405 		return $variations;
       
  3406 	};
       
  3407 
       
  3408 	/**
       
  3409 	 * Builds the font-family's CSS.
       
  3410 	 *
       
  3411 	 * @since 6.0.0
       
  3412 	 *
       
  3413 	 * @uses $fn_compile_src To run the function that compiles the src.
       
  3414 	 * @uses $fn_compile_variations To run the function that compiles the variations.
       
  3415 	 *
       
  3416 	 * @param array $webfont Webfont to process.
       
  3417 	 * @return string This font-family's CSS.
       
  3418 	 */
       
  3419 	$fn_build_font_face_css = static function( array $webfont ) use ( $fn_compile_src, $fn_compile_variations ) {
       
  3420 		$css = '';
       
  3421 
       
  3422 		// Wrap font-family in quotes if it contains spaces.
       
  3423 		if (
       
  3424 			str_contains( $webfont['font-family'], ' ' ) &&
       
  3425 			! str_contains( $webfont['font-family'], '"' ) &&
       
  3426 			! str_contains( $webfont['font-family'], "'" )
       
  3427 		) {
       
  3428 			$webfont['font-family'] = '"' . $webfont['font-family'] . '"';
       
  3429 		}
       
  3430 
       
  3431 		foreach ( $webfont as $key => $value ) {
       
  3432 			/*
       
  3433 			 * Skip "provider", since it's for internal API use,
       
  3434 			 * and not a valid CSS property.
       
  3435 			 */
       
  3436 			if ( 'provider' === $key ) {
       
  3437 				continue;
       
  3438 			}
       
  3439 
       
  3440 			// Compile the "src" parameter.
       
  3441 			if ( 'src' === $key ) {
       
  3442 				$value = $fn_compile_src( $webfont['font-family'], $value );
       
  3443 			}
       
  3444 
       
  3445 			// If font-variation-settings is an array, convert it to a string.
       
  3446 			if ( 'font-variation-settings' === $key && is_array( $value ) ) {
       
  3447 				$value = $fn_compile_variations( $value );
       
  3448 			}
       
  3449 
       
  3450 			if ( ! empty( $value ) ) {
       
  3451 				$css .= "$key:$value;";
       
  3452 			}
       
  3453 		}
       
  3454 
       
  3455 		return $css;
       
  3456 	};
       
  3457 
       
  3458 	/**
       
  3459 	 * Gets the '@font-face' CSS styles for locally-hosted font files.
       
  3460 	 *
       
  3461 	 * @since 6.0.0
       
  3462 	 *
       
  3463 	 * @uses $registered_webfonts To access and update the registered webfonts registry (passed by reference).
       
  3464 	 * @uses $fn_order_src To run the function that orders the src.
       
  3465 	 * @uses $fn_build_font_face_css To run the function that builds the font-face CSS.
       
  3466 	 *
       
  3467 	 * @return string The `@font-face` CSS.
       
  3468 	 */
       
  3469 	$fn_get_css = static function() use ( &$registered_webfonts, $fn_order_src, $fn_build_font_face_css ) {
       
  3470 		$css = '';
       
  3471 
       
  3472 		foreach ( $registered_webfonts as $webfont ) {
       
  3473 			// Order the webfont's `src` items to optimize for browser support.
       
  3474 			$webfont = $fn_order_src( $webfont );
       
  3475 
       
  3476 			// Build the @font-face CSS for this webfont.
       
  3477 			$css .= '@font-face{' . $fn_build_font_face_css( $webfont ) . '}';
       
  3478 		}
       
  3479 
       
  3480 		return $css;
       
  3481 	};
       
  3482 
       
  3483 	/**
       
  3484 	 * Generates and enqueues webfonts styles.
       
  3485 	 *
       
  3486 	 * @since 6.0.0
       
  3487 	 *
       
  3488 	 * @uses $fn_get_css To run the function that gets the CSS.
       
  3489 	 */
       
  3490 	$fn_generate_and_enqueue_styles = static function() use ( $fn_get_css ) {
       
  3491 		// Generate the styles.
       
  3492 		$styles = $fn_get_css();
       
  3493 
       
  3494 		// Bail out if there are no styles to enqueue.
       
  3495 		if ( '' === $styles ) {
       
  3496 			return;
       
  3497 		}
       
  3498 
       
  3499 		// Enqueue the stylesheet.
       
  3500 		wp_register_style( 'wp-webfonts', '' );
       
  3501 		wp_enqueue_style( 'wp-webfonts' );
       
  3502 
       
  3503 		// Add the styles to the stylesheet.
       
  3504 		wp_add_inline_style( 'wp-webfonts', $styles );
       
  3505 	};
       
  3506 
       
  3507 	/**
       
  3508 	 * Generates and enqueues editor styles.
       
  3509 	 *
       
  3510 	 * @since 6.0.0
       
  3511 	 *
       
  3512 	 * @uses $fn_get_css To run the function that gets the CSS.
       
  3513 	 */
       
  3514 	$fn_generate_and_enqueue_editor_styles = static function() use ( $fn_get_css ) {
       
  3515 		// Generate the styles.
       
  3516 		$styles = $fn_get_css();
       
  3517 
       
  3518 		// Bail out if there are no styles to enqueue.
       
  3519 		if ( '' === $styles ) {
       
  3520 			return;
       
  3521 		}
       
  3522 
       
  3523 		wp_add_inline_style( 'wp-block-library', $styles );
       
  3524 	};
       
  3525 
       
  3526 	add_action( 'wp_loaded', $fn_register_webfonts );
       
  3527 	add_action( 'wp_enqueue_scripts', $fn_generate_and_enqueue_styles );
       
  3528 	add_action( 'admin_init', $fn_generate_and_enqueue_editor_styles );
       
  3529 }