max( 2 * $wide, $width ) ]; } $out = []; if ( preg_match_all( '/(\S+)\s+(\d+)w/', (string) wp_get_attachment_image_srcset( $id, 'full' ), $m, PREG_SET_ORDER ) ) { foreach ( $m as [ , $u, $w ] ) { $out[ $u ] = (int) $w; } } return $out ?: [ $url => $width ]; }; $rooster_srcset = static function ( array $candidates ): string { asort( $candidates ); return implode( ', ', array_map( static fn ( string $u, int $w ): string => esc_url( $u ) . " {$w}w", array_keys( $candidates ), $candidates ) ); }; $desktop = $rooster_candidates( $desktop_id, $desktop_url, $desktop_w, Images::COMPUTER ); $mobile = $rooster_candidates( $mobile_id, $mobile_url, $mobile_w, Images::PHONE ); asort( $mobile ); $fallback = (string) array_key_last( $mobile ); $sizes = trim( (string) ( $attributes['sizes'] ?? '' ) ); $slot = 0; if ( '' === $sizes ) { $align = (string) ( $attributes['align'] ?? '' ); $width = 'wide' === $align ? $wide : ( (int) ( $layout['contentSize'] ?? 720 ) ?: 720 ); $sizes = 'full' === $align ? '100vw' : sprintf( '(max-width: 781px) calc(100vw - 32px), (max-width: %dpx) calc(100vw - 80px), %dpx', $width + 80, $width ); $slot = 'full' === $align ? 0 : $width; } $rooster_first = static function ( array $candidates, int $need ): array { asort( $candidates ); $first = []; foreach ( $candidates as $url => $w ) { $first[ $url ] = $w; if ( $w >= $need ) { break; } } return $first; }; $sharpen = class_exists( Defer::class ) && Defer::enabled(); $desktop_first = $sharpen && $slot > 0 ? $rooster_first( $desktop, $slot ) : $desktop; $mobile_first = $sharpen && class_exists( DeviceClass::class ) && 'mobile' === DeviceClass::current() ? $rooster_first( $mobile, (int) apply_filters( 'rooster/responsive_image/first_width', 430 ) ) : $mobile; $rooster_vector = static function ( int $id, int $main ): string { if ( ! $id || 'image/svg+xml' !== get_post_mime_type( $id ) || 'image/svg+xml' === get_post_mime_type( $main ) ) { return ''; } return (string) wp_get_attachment_url( $id ); }; $desktop_vector = $rooster_vector( (int) ( $attributes['desktopVectorId'] ?? 0 ), $desktop_id ); $mobile_vector = $rooster_vector( (int) ( $attributes['mobileVectorId'] ?? 0 ) ?: ( $mobile_id === $desktop_id ? (int) ( $attributes['desktopVectorId'] ?? 0 ) : 0 ), $mobile_id ); $rooster_lists = static function ( array $first, array $all, string $vector ) use ( $sharpen, $wide ): array { if ( '' === $vector ) { return [ $first, count( $first ) < count( $all ) ? $all : [] ]; } $with = static fn ( array $list ): array => $list + [ $vector => max( 2 * $wide, max( $list ) + 1 ) ]; return $sharpen ? [ $first, $with( $first ) ] : [ $with( $all ), [] ]; }; [ $desktop_paint, $desktop_aside ] = $rooster_lists( $desktop_first, $desktop, $desktop_vector ); [ $mobile_paint, $mobile_aside ] = $rooster_lists( $mobile_first, $mobile, $mobile_vector ); if ( [] !== $desktop_aside || [] !== $mobile_aside ) { Defer::enqueue(); } $decorative = ! empty( $attributes['decorative'] ); $title = trim( (string) ( $attributes['title'] ?? '' ) ); $title = '' !== $title || $decorative ? $title : (string) get_the_title( $desktop_id ); $alt = $decorative ? '' : trim( (string) ( $attributes['desktopAlt'] ?? '' ) ); $alt = '' !== $alt || $decorative ? $alt : trim( (string) get_post_meta( $desktop_id, '_wp_attachment_image_alt', true ) ); $alt = '' !== $alt || $decorative ? $alt : $title; $m_alt = $decorative ? '' : trim( (string) ( $attributes['mobileAlt'] ?? '' ) ); $m_alt = '' !== $m_alt || $decorative ? $m_alt : $alt; $style = sprintf( '--rooster-img-ratio-desktop:%s;--rooster-img-ratio-mobile:%s;', $attributes['desktopAspectRatio'] ?: ( $desktop_h ? "$desktop_w/$desktop_h" : 'auto' ), $attributes['mobileAspectRatio'] ?: ( $mobile_h ? "$mobile_w/$mobile_h" : 'auto' ) ); $wrapper = get_block_wrapper_attributes( [ 'class' => 'rooster-responsive-image' . ( ! empty( $attributes['rounded'] ) ? ' rooster-responsive-image--rounded' : '' ), 'style' => $style ] ); $source = static fn ( string $media, array $paint, array $aside, int $w, int $h ): string => sprintf( '', esc_attr( $media ), esc_attr( $rooster_srcset( $paint ) ), esc_attr( $sizes ), $w, $h, [] !== $aside ? ' data-rooster-srcset="' . esc_attr( $rooster_srcset( $aside ) ) . '"' : '' ); $img = sprintf( '%s', esc_url( $fallback ), $mobile_w, $mobile_h, esc_attr( $m_alt ), '' !== $title ? ' title="' . esc_attr( $title ) . '"' : '', esc_attr( $loading ), $priority ? ' fetchpriority="' . esc_attr( $priority ) . '"' : '' ); if ( 'high' === $priority ) { $places = in_array( $attributes['align'] ?? '', [ 'wide', 'full' ], true ) ? wp_omit_loading_attr_threshold() : 1; if ( doing_filter( 'the_content' ) ) { $needle = 'src="' . esc_url( $fallback ) . '"'; $counter = static function ( $html ) use ( &$counter, $needle, $places ) { if ( str_contains( (string) $html, $needle ) ) { wp_increase_content_media_count( $places ); remove_filter( 'wp_content_img_tag', $counter ); } return $html; }; add_filter( 'wp_content_img_tag', $counter ); } else { wp_increase_content_media_count( $places ); } } $desktop_media = sprintf( '(min-width: %dpx)', $breakpoint + 1 ); $mobile_media = sprintf( '(max-width: %dpx)', $breakpoint ); $picture = '' . $source( $desktop_media, $desktop_paint, $desktop_aside, $desktop_w, $desktop_h ) . $source( $mobile_media, $mobile_paint, $mobile_aside, $mobile_w, $mobile_h ) . $img . ''; if ( 'high' === $priority ) { Performance::lcp_picture( [ [ 'media' => $desktop_media, 'href' => (string) array_key_first( $desktop_paint ), 'srcset' => $rooster_srcset( $desktop_paint ), 'sizes' => $sizes ], [ 'media' => $mobile_media, 'href' => (string) array_key_first( $mobile_paint ), 'srcset' => $rooster_srcset( $mobile_paint ), 'sizes' => $sizes ], ] ); } $href = rooster_esc_url_or_empty( (string) ( $attributes['href'] ?? '' ) ); if ( $href ) { AIEO_Engine_Blocks::out( sprintf( '%s', $href, $picture ) ); return; } AIEO_Engine_Blocks::out( $picture );