wpseek.com
Eine auf WordPress spezialiserte Suchmaschine für Entwickler und Theme-Autoren



wp_hoist_late_printed_styles › WordPress Function

Seit6.9.0
Veraltetn/v
wp_hoist_late_printed_styles ( Keine Parameter )
Siehe:
Definiert in:
Codex:

Adds the hooks needed for CSS output to be delayed until after the content of the page has been established.



Quellcode

function wp_hoist_late_printed_styles() {
	// Skip the embed template on-demand styles aren't relevant, and there is no wp_head action.
	if ( is_embed() ) {
		return;
	}

	/*
	 * While normally late styles are printed, there is a filter to disable prevent this, so this makes sure they are
	 * printed. Note that this filter was intended to control whether to print the styles queued too late for the HTML
	 * head. This filter was introduced in <https://core.trac.wordpress.org/ticket/9346>. However, with the template
	 * enhancement output buffer, essentially no style can be enqueued too late, because an output buffer filter can
	 * always hoist it to the HEAD.
	 */
	add_filter( 'print_late_styles', '__return_true', PHP_INT_MAX );

	/*
	 * Print a placeholder comment where the late styles can be hoisted from the footer to be printed in the header
	 * by means of a filter below on the template enhancement output buffer.
	 */
	$placeholder = sprintf( '/*%s*/', uniqid( 'wp_late_styles_placeholder:' ) );

	wp_add_inline_style( 'wp-block-library', $placeholder );

	// Wrap print_late_styles() with a closure that captures the late-printed styles.
	$printed_late_styles = '';
	$capture_late_styles = static function () use ( &$printed_late_styles ) {
		ob_start();
		print_late_styles();
		$printed_late_styles = ob_get_clean();
	};

	/*
	 * If _wp_footer_scripts() was unhooked from the wp_print_footer_scripts action, or if wp_print_footer_scripts()
	 * was unhooked from running at the wp_footer action, then only add a callback to wp_footer which will capture the
	 * late-printed styles.
	 *
	 * Otherwise, in the normal case where _wp_footer_scripts() will run at the wp_print_footer_scripts action, then
	 * swap out _wp_footer_scripts() with an alternative which captures the printed styles (for hoisting to HEAD) before
	 * proceeding with printing the footer scripts.
	 */
	$wp_print_footer_scripts_priority = has_action( 'wp_print_footer_scripts', '_wp_footer_scripts' );
	if ( false === $wp_print_footer_scripts_priority || false === has_action( 'wp_footer', 'wp_print_footer_scripts' ) ) {
		// The normal priority for wp_print_footer_scripts() is to run at 20.
		add_action( 'wp_footer', $capture_late_styles, 20 );
	} else {
		remove_action( 'wp_print_footer_scripts', '_wp_footer_scripts', $wp_print_footer_scripts_priority );
		add_action(
			'wp_print_footer_scripts',
			static function () use ( $capture_late_styles ) {
				$capture_late_styles();
				print_footer_scripts();
			},
			$wp_print_footer_scripts_priority
		);
	}

	// Replace placeholder with the captured late styles.
	add_filter(
		'wp_template_enhancement_output_buffer',
		function ( $buffer ) use ( $placeholder, &$printed_late_styles ) {

			// Anonymous subclass of WP_HTML_Tag_Processor which exposes underlying bookmark spans.
			$processor = new class( $buffer ) extends WP_HTML_Tag_Processor {
				public function get_span(): WP_HTML_Span {
					$instance = $this; // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewClosure.ThisFoundOutsideClass -- It is inside an anonymous class.
					$instance->set_bookmark( 'here' );
					return $instance->bookmarks['here'];
				}
			};

			// Loop over STYLE tags.
			while ( $processor->next_tag( array( 'tag_name' => 'STYLE' ) ) ) {
				// Skip to the next if this is not the inline style for the wp-block-library stylesheet (which contains the placeholder).
				if ( 'wp-block-library-inline-css' !== $processor->get_attribute( 'id' ) ) {
					continue;
				}

				// If the inline style lacks the placeholder comment, then something went wrong and we need to abort.
				$css_text = $processor->get_modifiable_text();
				if ( ! str_contains( $css_text, $placeholder ) ) {
					break;
				}

				// Remove the placeholder now that we've located the inline style.
				$processor->set_modifiable_text( str_replace( $placeholder, '', $css_text ) );
				$buffer = $processor->get_updated_html();

				// Insert the $printed_late_styles immediately after the closing inline STYLE tag. This preserves the CSS cascade.
				$span   = $processor->get_span();
				$buffer = implode(
					'',
					array(
						substr( $buffer, 0, $span->start + $span->length ),
						$printed_late_styles,
						substr( $buffer, $span->start + $span->length ),
					)
				);
				break;
			}

			return $buffer;
		}
	);
}