[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> script-loader.php (source)

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


Generated : Sat Dec 21 08:20:01 2024 Cross-referenced by PHPXref