1f427;', '🐨', '🐩', '🐪', '🐫', '🐬', '🐭', '🐮', '🐯', '🐰', '🐱', '🐲', '🐳', '🐴', '🐵', '🐶', '🐷', '🐸', '🐹', '🐺', '🐻', '❄', '🐼', '🐽', '🐾', '🐿', '👀', '👁', '🗨', '👂', '👃', '👄', '👅', '👆', '👇', '👈', '👉', '👊', '👋', '👌', '👍', '👎', '👏', '👐', '👑', '👒', '👓', '👔', '👕', '👖', '👗', '👘', '👙', '👚', '👛', '👜', '👝', '👞', '👟', '👠', '👡', '👢', '👣', '👤', '👥', '👦', '👧', '👨', '💻', '💼', '🔧', '🔬', '🚀', '🚒', '🤝', '🦯', '🦰', '🦱', '🦲', '🦳', '🦼', '🦽', '⚕', '⚖', '✈', '❤', '💋', '👩', '👪', '👫', '👬', '👭', '👮', '👯', '👰', '👱', '👲', '👳', '👴', '👵', '👶', '👷', '👸', '👹', '👺', '👻', '👼', '👽', '👾', '👿', '💀', '💁', '💂', '💃', '💄', '💅', '💆', '💇', '💈', '💉', '💊', '💌', '💍', '💎', '💏', '💐', '💑', '💒', '💓', '💔', '💕', '💖', '💗', '💘', '💙', '💚', '💛', '💜', '💝', '💞', '💟', '💠', '💡', '💢', '💣', '💤', '💥', '💦', '💧', '💨', '💩', '💪', '💫', '💬', '💭', '💮', '💯', '💰', '💱', '💲', '💳', '💴', '💵', '💶', '💷', '💸', '💹', '💺', '💽', '💾', '💿', '📀', '📁', '📂', '📃', '📄', '📅', '📆', '📇', '📈', '📉', '📊', '📋', '📌', '📍', '📎', '📏', '📐', '📑', '📒', '📓', '📔', '📕', '📖', '📗', '📘', '📙', '📚', '📛', '📜', '📝', '📞', '📟', '📠', '📡', '📢', '📣', '📤', '📥', '📦', '📧', '📨', '📩', '📪', '📫', '📬', '📭', '📮', '📯', '📰', '📱', '📲', '📳', '📴', '📵', '📶', '📷', '📸', '📹', '📺', '📻', '📼', '📽', '📿', '🔀', '🔁', '🔂', '🔃', '🔄', '🔅', '🔆', '🔇', '🔈', '🔉', '🔊', '🔋', '🔌', '🔍', '🔎', '🔏', '🔐', '🔑', '🔒', '🔓', '🔔', '🔕', '🔖', '🔗', '🔘', '🔙', '🔚', '🔛', '🔜', '🔝', '🔞', '🔟', '🔠', '🔡', '🔢', '🔣', '🔤', '🔥', '🔦', '🔨', '🔩', '🔪', '🔫', '🔭', '🔮', '🔯', '🔰', '🔱', '🔲', '🔳', '🔴', '🔵', '🔶', '🔷', '🔸', '🔹', '🔺', '🔻', '🔼', '🔽', '🕉', '🕊', '🕋', '🕌', '🕍', '🕎', '🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛', '🕜', '🕝', '🕞', '🕟', '🕠', '🕡', '🕢', '🕣', '🕤', '🕥', '🕦', '🕧', '🕯', '🕰', '🕳', '🕴', '🕵', '🕶', '🕷', '🕸', '🕹', '🕺', '🖇', '🖊', '🖋', '🖌', '🖍', '🖐', '🖕', '🖖', '🖤', '🖥', '🖨', '🖱', '🖲', '🖼', '🗂', '🗃', '🗄', '🗑', '🗒', '🗓', '🗜', '🗝', '🗞', '🗡', '🗣', '🗯', '🗳', '🗺', '🗻', '🗼', '🗽', '🗾', '🗿', '😀', '😁', '😂', '😃', '😄', '😅', '😆', '😇', '😈', '😉', '😊', '😋', '😌', '😍', '😎', '😏', '😐', '😑', '😒', '😓', '😔', '😕', '😖', '😗', '😘', '😙', '😚', '😛', '😜', '😝', '😞', '😟', '😠', '😡', '😢', '😣', '😤', '😥', '😦', '😧', '😨', '😩', '😪', '😫', '😬', '😭', '😮', '😯', '😰', '😱', '😲', '😳', '😴', '😵', '😶', '😷', '😸', '😹', '😺', '😻', '😼', '😽', '😾', '😿', '🙀', '🙁', '🙂', '🙃', '🙄', '🙅', '🙆', '🙇', '🙈', '🙉', '🙊', '🙋', '🙌', '🙍', '🙎', '🙏', '🚁', '🚂', '🚃', '🚄', '🚅', '🚆', '🚇', '🚈', '🚉', '🚊', '🚋', '🚌', '🚍', '🚎', '🚏', '🚐', '🚑', '🚓', '🚔', '🚕', '🚖', '🚗', '🚘', '🚙', '🚚', '🚛', '🚜', '🚝', '🚞', '🚟', '🚠', '🚡', '🚢', '🚣', '🚤', '🚥', '🚦', '🚧', '🚨', '🚩', '🚪', '🚫', '🚬', '🚭', '🚮', '🚯', '🚰', '🚱', '🚲', '🚳', '🚴', '🚵', '🚶', '🚷', '🚸', '🚹', '🚺', '🚻', '🚼', '🚽', '🚾', '🚿', '🛀', '🛁', '🛂', '🛃', '🛄', '🛅', '🛋', '🛌', '🛍', '🛎', '🛏', '🛐', '🛑', '🛒', '🛕', '🛖', '🛗', '🛜', '🛝', '🛞', '🛟', '🛠', '🛡', '🛢', '🛣', '🛤', '🛥', '🛩', '🛫', '🛬', '🛰', '🛳', '🛴', '🛵', '🛶', '🛷', '🛸', '🛹', '🛺', '🛻', '🛼', '🟠', '🟡', '🟢', '🟣', '🟤', '🟥', '🟦', '🟧', '🟨', '🟩', '🟪', '🟫', '🟰', '🤌', '🤍', '🤎', '🤏', '🤐', '🤑', '🤒', '🤓', '🤔', '🤕', '🤖', '🤗', '🤘', '🤙', '🤚', '🤛', '🤜', '🤞', '🤟', '🤠', '🤡', '🤢', '🤣', '🤤', '🤥', '🤦', '🤧', '🤨', '🤩', '🤪', '🤫', '🤬', '🤭', '🤮', '🤯', '🤰', '🤱', '🤲', '🤳', '🤴', '🤵', '🤶', '🤷', '🤸', '🤹', '🤺', '🤼', '🤽', '🤾', '🤿', '🥀', '🥁', '🥂', '🥃', '🥄', '🥅', '🥇', '🥈', '🥉', '🥊', '🥋', '🥌', '🥍', '🥎', '🥏', '🥐', '🥑', '🥒', '🥓', '🥔', '🥕', '🥖', '🥗', '🥘', '🥙', '🥚', '🥛', '🥜', '🥝', '🥞', '🥟', '🥠', '🥡', '🥢', '🥣', '🥤', '🥥', '🥦', '🥧', '🥨', '🥩', '🥪', '🥫', '🥬', '🥭', '🥮', '🥯', '🥰', '🥱', '🥲', '🥳', '🥴', '🥵', '🥶', '🥷', '🥸', '🥹', '🥺', '🥻', '🥼', '🥽', '🥾', '🥿', '🦀', '🦁', '🦂', '🦃', '🦄', '🦅', '🦆', '🦇', '🦈', '🦉', '🦊', '🦋', '🦌', '🦍', '🦎', '🦏', '🦐', '🦑', '🦒', '🦓', '🦔', '🦕', '🦖', '🦗', '🦘', '🦙', '🦚', '🦛', '🦜', '🦝', '🦞', '🦟', '🦠', '🦡', '🦢', '🦣', '🦤', '🦥', '🦦', '🦧', '🦨', '🦩', '🦪', '🦫', '🦬', '🦭', '🦮', '🦴', '🦵', '🦶', '🦷', '🦸', '🦹', '🦻', '🦾', '🦿', '🧀', '🧁', '🧂', '🧃', '🧄', '🧅', '🧆', '🧇', '🧈', '🧉', '🧊', '🧋', '🧌', '🧍', '🧎', '🧏', '🧐', '🧑', '🧒', '🧓', '🧔', '🧕', '🧖', '🧗', '🧘', '🧙', '🧚', '🧛', '🧜', '🧝', '🧞', '🧟', '🧠', '🧡', '🧢', '🧣', '🧤', '🧥', '🧦', '🧧', '🧨', '🧩', '🧪', '🧫', '🧬', '🧭', '🧮', '🧯', '🧰', '🧱', '🧲', '🧳', '🧴', '🧵', '🧶', '🧷', '🧸', '🧹', '🧺', '🧻', '🧼', '🧽', '🧾', '🧿', '🩰', '🩱', '🩲', '🩳', '🩴', '🩵', '🩶', '🩷', '🩸', '🩹', '🩺', '🩻', '🩼', '🪀', '🪁', '🪂', '🪃', '🪄', '🪅', '🪆', '🪇', '🪈', '🪐', '🪑', '🪒', '🪓', '🪔', '🪕', '🪖', '🪗', '🪘', '🪙', '🪚', '🪛', '🪜', '🪝', '🪞', '🪟', '🪠', '🪡', '🪢', '🪣', '🪤', '🪥', '🪦', '🪧', '🪨', '🪩', '🪪', '🪫', '🪬', '🪭', '🪮', '🪯', '🪰', '🪱', '🪲', '🪳', '🪴', '🪵', '🪶', '🪷', '🪸', '🪹', '🪺', '🪻', '🪼', '🪽', '🪿', '🫀', '🫁', '🫂', '🫃', '🫄', '🫅', '🫎', '🫏', '🫐', '🫑', '🫒', '🫓', '🫔', '🫕', '🫖', '🫗', '🫘', '🫙', '🫚', '🫛', '🫠', '🫡', '🫢', '🫣', '🫤', '🫥', '🫦', '🫧', '🫨', '🫰', '🫱', '🫲', '🫳', '🫴', '🫵', '🫶', '🫷', '🫸', '‼', '⁉', '™', 'ℹ', '↔', '↕', '↖', '↗', '↘', '↙', '↩', '↪', '⃣', '⌚', '⌛', '⌨', '⏏', '⏩', '⏪', '⏫', '⏬', '⏭', '⏮', '⏯', '⏰', '⏱', '⏲', '⏳', '⏸', '⏹', '⏺', 'Ⓜ', '▪', '▫', '▶', '◀', '◻', '◼', '◽', '◾', '☀', '☁', '☂', '☃', '☄', '☎', '☑', '☔', '☕', '☘', '☝', '☢', '☣', '☦', '☪', '☮', '☯', '☸', '☹', '☺', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '♟', '♠', '♣', '♥', '♦', '♨', '♻', '♾', '♿', '⚒', '⚓', '⚔', '⚗', '⚙', '⚛', '⚜', '⚠', '⚡', '⚪', '⚫', '⚰', '⚱', '⚽', '⚾', '⛄', '⛅', '⛈', '⛎', '⛏', '⛑', '⛓', '⛔', '⛩', '⛪', '⛰', '⛱', '⛲', '⛳', '⛴', '⛵', '⛷', '⛸', '⛹', '⛺', '⛽', '✂', '✅', '✉', '✊', '✋', '✌', '✍', '✏', '✒', '✔', '✖', '✝', '✡', '✨', '✳', '✴', '❇', '❌', '❎', '❓', '❔', '❕', '❗', '❣', '➕', '➖', '➗', '➡', '➰', '➿', '⤴', '⤵', '⬅', '⬆', '⬇', '⬜', '⭐', '⭕', '〰', '〽', '㊗', '㊙', '' );
// END: emoji arrays
if ( 'entities' === $type ) {
return $entities;
}
return $partials;
}
/**
* Shortens a URL, to be used as link text.
*
* @since 1.2.0
* @since 4.4.0 Moved to wp-includes/formatting.php from wp-admin/includes/misc.php and added $length param.
*
* @param string $url URL to shorten.
* @param int $length Optional. Maximum length of the shortened URL. Default 35 characters.
* @return string Shortened URL.
*/
function url_shorten( $url, $length = 35 ) {
$stripped = str_replace( array( 'https://', 'http://', 'www.' ), '', $url );
$short_url = untrailingslashit( $stripped );
if ( strlen( $short_url ) > $length ) {
$short_url = substr( $short_url, 0, $length - 3 ) . '…';
}
return $short_url;
}
/**
* Sanitizes a hex color.
*
* Returns either '', a 3 or 6 digit hex color (with #), or nothing.
* For sanitizing values without a #, see sanitize_hex_color_no_hash().
*
* @since 3.4.0
*
* @param string $color
* @return string|void
*/
function sanitize_hex_color( $color ) {
if ( '' === $color ) {
return '';
}
// 3 or 6 hex digits, or the empty string.
if ( preg_match( '|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) {
return $color;
}
}
/**
* Sanitizes a hex color without a hash. Use sanitize_hex_color() when possible.
*
* Saving hex colors without a hash puts the burden of adding the hash on the
* UI, which makes it difficult to use or upgrade to other color types such as
* rgba, hsl, rgb, and HTML color names.
*
* Returns either '', a 3 or 6 digit hex color (without a #), or null.
*
* @since 3.4.0
*
* @param string $color
* @return string|null
*/
function sanitize_hex_color_no_hash( $color ) {
$color = ltrim( $color, '#' );
if ( '' === $color ) {
return '';
}
return sanitize_hex_color( '#' . $color ) ? $color : null;
}
/**
* Ensures that any hex color is properly hashed.
* Otherwise, returns value untouched.
*
* This method should only be necessary if using sanitize_hex_color_no_hash().
*
* @since 3.4.0
*
* @param string $color
* @return string
*/
function maybe_hash_hex_color( $color ) {
$unhashed = sanitize_hex_color_no_hash( $color );
if ( $unhashed ) {
return '#' . $unhashed;
}
return $color;
}
=> '2.29.4',
'lodash' => '4.17.21',
'wp-polyfill-fetch' => '3.6.17',
'wp-polyfill-formdata' => '4.0.10',
'wp-polyfill-node-contains' => '4.8.0',
'wp-polyfill-url' => '3.6.4',
'wp-polyfill-dom-rect' => '4.8.0',
'wp-polyfill-element-closest' => '3.0.2',
'wp-polyfill-object-fit' => '2.3.5',
'wp-polyfill-inert' => '3.1.2',
'wp-polyfill' => '3.15.0',
'wp-polyfill-importmap' => '1.8.2',
);
foreach ( $vendor_scripts as $handle => $dependencies ) {
if ( is_string( $dependencies ) ) {
$handle = $dependencies;
$dependencies = array();
}
$path = "/wp-includes/js/dist/vendor/$handle$suffix.js";
$version = $vendor_scripts_versions[ $handle ];
$scripts->add( $handle, $path, $dependencies, $version, 1 );
}
did_action( 'init' ) && $scripts->add_inline_script( 'lodash', 'window.lodash = _.noConflict();' );
did_action( 'init' ) && $scripts->add_inline_script(
'moment',
sprintf(
"moment.updateLocale( '%s', %s );",
esc_js( get_user_locale() ),
wp_json_encode(
array(
'months' => array_values( $wp_locale->month ),
'monthsShort' => array_values( $wp_locale->month_abbrev ),
'weekdays' => array_values( $wp_locale->weekday ),
'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ),
'week' => array(
'dow' => (int) get_option( 'start_of_week', 0 ),
),
'longDateFormat' => array(
'LT' => get_option( 'time_format', __( 'g:i a' ) ),
'LTS' => null,
'L' => null,
'LL' => get_option( 'date_format', __( 'F j, Y' ) ),
'LLL' => __( 'F j, Y g:i a' ),
'LLLL' => null,
),
)
)
),
'after'
);
}
/**
* Returns contents of an inline script used in appending polyfill scripts for
* browsers which fail the provided tests. The provided array is a mapping from
* a condition to verify feature support to its polyfill script handle.
*
* @since 5.0.0
*
* @param WP_Scripts $scripts WP_Scripts object.
* @param string[] $tests Features to detect.
* @return string Conditional polyfill inline script.
*/
function wp_get_script_polyfill( $scripts, $tests ) {
$polyfill = '';
foreach ( $tests as $test => $handle ) {
if ( ! array_key_exists( $handle, $scripts->registered ) ) {
continue;
}
$src = $scripts->registered[ $handle ]->src;
$ver = $scripts->registered[ $handle ]->ver;
if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $scripts->content_url && str_starts_with( $src, $scripts->content_url ) ) ) {
$src = $scripts->base_url . $src;
}
if ( ! empty( $ver ) ) {
$src = add_query_arg( 'ver', $ver, $src );
}
/** This filter is documented in wp-includes/class-wp-scripts.php */
$src = esc_url( apply_filters( 'script_loader_src', $src, $handle ) );
if ( ! $src ) {
continue;
}
$polyfill .= (
// Test presence of feature...
'( ' . $test . ' ) || ' .
/*
* ...appending polyfill on any failures. Cautious viewers may balk
* at the `document.write`. Its caveat of synchronous mid-stream
* blocking write is exactly the behavior we need though.
*/
'document.write( \'\n";
}
$concat = str_split( $concat, 128 );
$concatenated = '';
foreach ( $concat as $key => $chunk ) {
$concatenated .= "&load%5Bchunk_{$key}%5D={$chunk}";
}
$src = $wp_scripts->base_url . "/wp-admin/load-scripts.php?c={$zip}" . $concatenated . '&ver=' . $wp_scripts->default_version;
echo "\n";
}
if ( ! empty( $wp_scripts->print_html ) ) {
echo $wp_scripts->print_html;
}
}
/**
* Prints the script queue in the HTML head on the front end.
*
* Postpones the scripts that were queued for the footer.
* wp_print_footer_scripts() is called in the footer to print these scripts.
*
* @since 2.8.0
*
* @global WP_Scripts $wp_scripts
*
* @return array
*/
function wp_print_head_scripts() {
global $wp_scripts;
if ( ! did_action( 'wp_print_scripts' ) ) {
/** This action is documented in wp-includes/functions.wp-scripts.php */
do_action( 'wp_print_scripts' );
}
if ( ! ( $wp_scripts instanceof WP_Scripts ) ) {
return array(); // No need to run if nothing is queued.
}
return print_head_scripts();
}
/**
* Private, for use in *_footer_scripts hooks
*
* @since 3.3.0
*/
function _wp_footer_scripts() {
print_late_styles();
print_footer_scripts();
}
/**
* Hooks to print the scripts and styles in the footer.
*
* @since 2.8.0
*/
function wp_print_footer_scripts() {
/**
* Fires when footer scripts are printed.
*
* @since 2.8.0
*/
do_action( 'wp_print_footer_scripts' );
}
/**
* Wrapper for do_action( 'wp_enqueue_scripts' ).
*
* Allows plugins to queue scripts for the front end using wp_enqueue_script().
* Runs first in wp_head() where all is_home(), is_page(), etc. functions are available.
*
* @since 2.8.0
*/
function wp_enqueue_scripts() {
/**
* Fires when scripts and styles are enqueued.
*
* @since 2.8.0
*/
do_action( 'wp_enqueue_scripts' );
}
/**
* Prints the styles queue in the HTML head on admin pages.
*
* @since 2.8.0
*
* @global bool $concatenate_scripts
*
* @return array
*/
function print_admin_styles() {
global $concatenate_scripts;
$wp_styles = wp_styles();
script_concat_settings();
$wp_styles->do_concat = $concatenate_scripts;
$wp_styles->do_items( false );
/**
* Filters whether to print the admin styles.
*
* @since 2.8.0
*
* @param bool $print Whether to print the admin styles. Default true.
*/
if ( apply_filters( 'print_admin_styles', true ) ) {
_print_styles();
}
$wp_styles->reset();
return $wp_styles->done;
}
/**
* Prints the styles that were queued too late for the HTML head.
*
* @since 3.3.0
*
* @global WP_Styles $wp_styles
* @global bool $concatenate_scripts
*
* @return array|void
*/
function print_late_styles() {
global $wp_styles, $concatenate_scripts;
if ( ! ( $wp_styles instanceof WP_Styles ) ) {
return;
}
script_concat_settings();
$wp_styles->do_concat = $concatenate_scripts;
$wp_styles->do_footer_items();
/**
* Filters whether to print the styles queued too late for the HTML head.
*
* @since 3.3.0
*
* @param bool $print Whether to print the 'late' styles. Default true.
*/
if ( apply_filters( 'print_late_styles', true ) ) {
_print_styles();
}
$wp_styles->reset();
return $wp_styles->done;
}
/**
* Prints styles (internal use only).
*
* @ignore
* @since 3.3.0
*
* @global bool $compress_css
*/
function _print_styles() {
global $compress_css;
$wp_styles = wp_styles();
$zip = $compress_css ? 1 : 0;
if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP ) {
$zip = 'gzip';
}
$concat = trim( $wp_styles->concat, ', ' );
$type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"';
if ( $concat ) {
$dir = $wp_styles->text_direction;
$ver = $wp_styles->default_version;
$concat = str_split( $concat, 128 );
$concatenated = '';
foreach ( $concat as $key => $chunk ) {
$concatenated .= "&load%5Bchunk_{$key}%5D={$chunk}";
}
$href = $wp_styles->base_url . "/wp-admin/load-styles.php?c={$zip}&dir={$dir}" . $concatenated . '&ver=' . $ver;
echo "\n";
if ( ! empty( $wp_styles->print_code ) ) {
echo "\n";
}
}
if ( ! empty( $wp_styles->print_html ) ) {
echo $wp_styles->print_html;
}
}
/**
* Determines the concatenation and compression settings for scripts and styles.
*
* @since 2.8.0
*
* @global bool $concatenate_scripts
* @global bool $compress_scripts
* @global bool $compress_css
*/
function script_concat_settings() {
global $concatenate_scripts, $compress_scripts, $compress_css;
$compressed_output = ( ini_get( 'zlib.output_compression' ) || 'ob_gzhandler' === ini_get( 'output_handler' ) );
$can_compress_scripts = ! wp_installing() && get_site_option( 'can_compress_scripts' );
if ( ! isset( $concatenate_scripts ) ) {
$concatenate_scripts = defined( 'CONCATENATE_SCRIPTS' ) ? CONCATENATE_SCRIPTS : true;
if ( ( ! is_admin() && ! did_action( 'login_init' ) ) || ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ) {
$concatenate_scripts = false;
}
}
if ( ! isset( $compress_scripts ) ) {
$compress_scripts = defined( 'COMPRESS_SCRIPTS' ) ? COMPRESS_SCRIPTS : true;
if ( $compress_scripts && ( ! $can_compress_scripts || $compressed_output ) ) {
$compress_scripts = false;
}
}
if ( ! isset( $compress_css ) ) {
$compress_css = defined( 'COMPRESS_CSS' ) ? COMPRESS_CSS : true;
if ( $compress_css && ( ! $can_compress_scripts || $compressed_output ) ) {
$compress_css = false;
}
}
}
/**
* Handles the enqueueing of block scripts and styles that are common to both
* the editor and the front-end.
*
* @since 5.0.0
*/
function wp_common_block_scripts_and_styles() {
if ( is_admin() && ! wp_should_load_block_editor_scripts_and_styles() ) {
return;
}
wp_enqueue_style( 'wp-block-library' );
if ( current_theme_supports( 'wp-block-styles' ) && ! wp_should_load_separate_core_block_assets() ) {
wp_enqueue_style( 'wp-block-library-theme' );
}
/**
* Fires after enqueuing block assets for both editor and front-end.
*
* Call `add_action` on any hook before 'wp_enqueue_scripts'.
*
* In the function call you supply, simply use `wp_enqueue_script` and
* `wp_enqueue_style` to add your functionality to the Gutenberg editor.
*
* @since 5.0.0
*/
do_action( 'enqueue_block_assets' );
}
/**
* Applies a filter to the list of style nodes that comes from WP_Theme_JSON::get_style_nodes().
*
* This particular filter removes all of the blocks from the array.
*
* We want WP_Theme_JSON to be ignorant of the implementation details of how the CSS is being used.
* This filter allows us to modify the output of WP_Theme_JSON depending on whether or not we are
* loading separate assets, without making the class aware of that detail.
*
* @since 6.1.0
*
* @param array $nodes The nodes to filter.
* @return array A filtered array of style nodes.
*/
function wp_filter_out_block_nodes( $nodes ) {
return array_filter(
$nodes,
static function ( $node ) {
return ! in_array( 'blocks', $node['path'], true );
},
ARRAY_FILTER_USE_BOTH
);
}
/**
* Enqueues the global styles defined via theme.json.
*
* @since 5.8.0
*/
function wp_enqueue_global_styles() {
$separate_assets = wp_should_load_separate_core_block_assets();
$is_block_theme = wp_is_block_theme();
$is_classic_theme = ! $is_block_theme;
/*
* Global styles should be printed in the head when loading all styles combined.
* The footer should only be used to print global styles for classic themes with separate core assets enabled.
*
* See https://core.trac.wordpress.org/ticket/53494.
*/
if (
( $is_block_theme && doing_action( 'wp_footer' ) ) ||
( $is_classic_theme && doing_action( 'wp_footer' ) && ! $separate_assets ) ||
( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) && $separate_assets )
) {
return;
}
/*
* If loading the CSS for each block separately, then load the theme.json CSS conditionally.
* This removes the CSS from the global-styles stylesheet and adds it to the inline CSS for each block.
* This filter must be registered before calling wp_get_global_stylesheet();
*/
add_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' );
$stylesheet = wp_get_global_stylesheet();
if ( empty( $stylesheet ) ) {
return;
}
wp_register_style( 'global-styles', false );
wp_add_inline_style( 'global-styles', $stylesheet );
wp_enqueue_style( 'global-styles' );
// Add each block as an inline css.
wp_add_global_styles_for_blocks();
}
/**
* Enqueues the global styles custom css defined via theme.json.
*
* @since 6.2.0
*/
function wp_enqueue_global_styles_custom_css() {
if ( ! wp_is_block_theme() ) {
return;
}
// Don't enqueue Customizer's custom CSS separately.
remove_action( 'wp_head', 'wp_custom_css_cb', 101 );
$custom_css = wp_get_custom_css();
$custom_css .= wp_get_global_styles_custom_css();
if ( ! empty( $custom_css ) ) {
wp_add_inline_style( 'global-styles', $custom_css );
}
}
/**
* Checks if the editor scripts and styles for all registered block types
* should be enqueued on the current screen.
*
* @since 5.6.0
*
* @global WP_Screen $current_screen WordPress current screen object.
*
* @return bool Whether scripts and styles should be enqueued.
*/
function wp_should_load_block_editor_scripts_and_styles() {
global $current_screen;
$is_block_editor_screen = ( $current_screen instanceof WP_Screen ) && $current_screen->is_block_editor();
/**
* Filters the flag that decides whether or not block editor scripts and styles
* are going to be enqueued on the current screen.
*
* @since 5.6.0
*
* @param bool $is_block_editor_screen Current value of the flag.
*/
return apply_filters( 'should_load_block_editor_scripts_and_styles', $is_block_editor_screen );
}
/**
* Checks whether separate styles should be loaded for core blocks on-render.
*
* When this function returns true, other functions ensure that core blocks
* only load their assets on-render, and each block loads its own, individual
* assets. Third-party blocks only load their assets when rendered.
*
* When this function returns false, all core block assets are loaded regardless
* of whether they are rendered in a page or not, because they are all part of
* the `block-library/style.css` file. Assets for third-party blocks are always
* enqueued regardless of whether they are rendered or not.
*
* This only affects front end and not the block editor screens.
*
* @see wp_enqueue_registered_block_scripts_and_styles()
* @see register_block_style_handle()
*
* @since 5.8.0
*
* @return bool Whether separate assets will be loaded.
*/
function wp_should_load_separate_core_block_assets() {
if ( is_admin() || is_feed() || wp_is_rest_endpoint() ) {
return false;
}
/**
* Filters whether block styles should be loaded separately.
*
* Returning false loads all core block assets, regardless of whether they are rendered
* in a page or not. Returning true loads core block assets only when they are rendered.
*
* @since 5.8.0
*
* @param bool $load_separate_assets Whether separate assets will be loaded.
* Default false (all block assets are loaded, even when not used).
*/
return apply_filters( 'should_load_separate_core_block_assets', false );
}
/**
* Enqueues registered block scripts and styles, depending on current rendered
* context (only enqueuing editor scripts while in context of the editor).
*
* @since 5.0.0
*
* @global WP_Screen $current_screen WordPress current screen object.
*/
function wp_enqueue_registered_block_scripts_and_styles() {
global $current_screen;
if ( wp_should_load_separate_core_block_assets() ) {
return;
}
$load_editor_scripts_and_styles = is_admin() && wp_should_load_block_editor_scripts_and_styles();
$block_registry = WP_Block_Type_Registry::get_instance();
foreach ( $block_registry->get_all_registered() as $block_name => $block_type ) {
// Front-end and editor styles.
foreach ( $block_type->style_handles as $style_handle ) {
wp_enqueue_style( $style_handle );
}
// Front-end and editor scripts.
foreach ( $block_type->script_handles as $script_handle ) {
wp_enqueue_script( $script_handle );
}
if ( $load_editor_scripts_and_styles ) {
// Editor styles.
foreach ( $block_type->editor_style_handles as $editor_style_handle ) {
wp_enqueue_style( $editor_style_handle );
}
// Editor scripts.
foreach ( $block_type->editor_script_handles as $editor_script_handle ) {
wp_enqueue_script( $editor_script_handle );
}
}
}
}
/**
* Function responsible for enqueuing the styles required for block styles functionality on the editor and on the frontend.
*
* @since 5.3.0
*
* @global WP_Styles $wp_styles
*/
function enqueue_block_styles_assets() {
global $wp_styles;
$block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered();
foreach ( $block_styles as $block_name => $styles ) {
foreach ( $styles as $style_properties ) {
if ( isset( $style_properties['style_handle'] ) ) {
// If the site loads separate styles per-block, enqueue the stylesheet on render.
if ( wp_should_load_separate_core_block_assets() ) {
add_filter(
'render_block',
static function ( $html, $block ) use ( $block_name, $style_properties ) {
if ( $block['blockName'] === $block_name ) {
wp_enqueue_style( $style_properties['style_handle'] );
}
return $html;
},
10,
2
);
} else {
wp_enqueue_style( $style_properties['style_handle'] );
}
}
if ( isset( $style_properties['inline_style'] ) ) {
// Default to "wp-block-library".
$handle = 'wp-block-library';
// If the site loads separate styles per-block, check if the block has a stylesheet registered.
if ( wp_should_load_separate_core_block_assets() ) {
$block_stylesheet_handle = generate_block_asset_handle( $block_name, 'style' );
if ( isset( $wp_styles->registered[ $block_stylesheet_handle ] ) ) {
$handle = $block_stylesheet_handle;
}
}
// Add inline styles to the calculated handle.
wp_add_inline_style( $handle, $style_properties['inline_style'] );
}
}
}
}
/**
* Function responsible for enqueuing the assets required for block styles functionality on the editor.
*
* @since 5.3.0
*/
function enqueue_editor_block_styles_assets() {
$block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered();
$register_script_lines = array( '( function() {' );
foreach ( $block_styles as $block_name => $styles ) {
foreach ( $styles as $style_properties ) {
$block_style = array(
'name' => $style_properties['name'],
'label' => $style_properties['label'],
);
if ( isset( $style_properties['is_default'] ) ) {
$block_style['isDefault'] = $style_properties['is_default'];
}
$register_script_lines[] = sprintf(
' wp.blocks.registerBlockStyle( \'%s\', %s );',
$block_name,
wp_json_encode( $block_style )
);
}
}
$register_script_lines[] = '} )();';
$inline_script = implode( "\n", $register_script_lines );
wp_register_script( 'wp-block-styles', false, array( 'wp-blocks' ), true, array( 'in_footer' => true ) );
wp_add_inline_script( 'wp-block-styles', $inline_script );
wp_enqueue_script( 'wp-block-styles' );
}
/**
* Enqueues the assets required for the block directory within the block editor.
*
* @since 5.5.0
*/
function wp_enqueue_editor_block_directory_assets() {
wp_enqueue_script( 'wp-block-directory' );
wp_enqueue_style( 'wp-block-directory' );
}
/**
* Enqueues the assets required for the format library within the block editor.
*
* @since 5.8.0
*/
function wp_enqueue_editor_format_library_assets() {
wp_enqueue_script( 'wp-format-library' );
wp_enqueue_style( 'wp-format-library' );
}
/**
* Sanitizes an attributes array into an attributes string to be placed inside a `\n", wp_sanitize_script_attributes( $attributes ) );
}
/**
* Prints formatted `
*
* In an HTML document this would print "…" to the console,
* but in an XHTML document it would print "…" to the console.
*
*
*
* In an HTML document this would print "An image is in HTML",
* but it's an invalid XHTML document because it interprets the ``
* as an empty tag missing its closing `/`.
*
* @see https://www.w3.org/TR/xhtml1/#h-4.8
*/
if (
! $is_html5 &&
(
! isset( $attributes['type'] ) ||
'module' === $attributes['type'] ||
str_contains( $attributes['type'], 'javascript' ) ||
str_contains( $attributes['type'], 'ecmascript' ) ||
str_contains( $attributes['type'], 'jscript' ) ||
str_contains( $attributes['type'], 'livescript' )
)
) {
/*
* If the string `]]>` exists within the JavaScript it would break
* out of any wrapping CDATA section added here, so to start, it's
* necessary to escape that sequence which requires splitting the
* content into two CDATA sections wherever it's found.
*
* Note: it's only necessary to escape the closing `]]>` because
* an additional `', ']]]]>', $data );
// Wrap the entire escaped script inside a CDATA section.
$data = sprintf( "/* */", $data );
}
$data = "\n" . trim( $data, "\n\r " ) . "\n";
/**
* Filters attributes to be added to a script tag.
*
* @since 5.7.0
*
* @param array $attributes Key-value pairs representing `\n", wp_sanitize_script_attributes( $attributes ), $data );
}
/**
* Prints an inline script tag.
*
* It is possible to inject attributes in the `" from
* around an inline script after trimming whitespace. Typically this
* is used in conjunction with output buffering, where `ob_get_clean()`
* is passed as the `$contents` argument.
*
* Example:
*
* // Strips exact literal empty SCRIPT tags.
* $js = ';
* 'sayHello();' === wp_remove_surrounding_empty_script_tags( $js );
*
* // Otherwise if anything is different it warns in the JS console.
* $js = '';
* 'console.error( ... )' === wp_remove_surrounding_empty_script_tags( $js );
*
* @since 6.4.0
* @access private
*
* @see wp_print_inline_script_tag()
* @see wp_get_inline_script_tag()
*
* @param string $contents Script body with manually created SCRIPT tag literals.
* @return string Script body without surrounding script tag literals, or
* original contents if both exact literals aren't present.
*/
function wp_remove_surrounding_empty_script_tags( $contents ) {
$contents = trim( $contents );
$opener = '';
if (
strlen( $contents ) > strlen( $opener ) + strlen( $closer ) &&
strtoupper( substr( $contents, 0, strlen( $opener ) ) ) === $opener &&
strtoupper( substr( $contents, -strlen( $closer ) ) ) === $closer
) {
return substr( $contents, strlen( $opener ), -strlen( $closer ) );
} else {
$error_message = __( 'Expected string to start with script tag (without attributes) and end with script tag, with optional whitespace.' );
_doing_it_wrong( __FUNCTION__, $error_message, '6.4' );
return sprintf(
'console.error(%s)',
wp_json_encode(
sprintf(
/* translators: %s: wp_remove_surrounding_empty_script_tags() */
__( 'Function %s used incorrectly in PHP.' ),
'wp_remove_surrounding_empty_script_tags()'
) . ' ' . $error_message
)
);
}
}