Skip to content

Instantly share code, notes, and snippets.

@westonruter
Last active September 14, 2023 22:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save westonruter/f37f747a57643462b7efe110dd61d91b to your computer and use it in GitHub Desktop.
Save westonruter/f37f747a57643462b7efe110dd61d91b to your computer and use it in GitHub Desktop.
<?php
/**
* Inline Image Size Fix Plugin for WordPress.
*
* @package InlineImageSizeFix
* @author Weston Ruter, Google
* @license GPL-2.0-or-later
* @copyright 2023 Google Inc.
*
* @wordpress-plugin
* Plugin Name: Inline Image Size Fix
* Description: When a large image is selected to be inserted in the block editor as an inline image, it is made artificially small. This can result in the image erroneously being given <code>fetchpriority=high</code> as well as <code>wp_img_tag_add_srcset_and_sizes_attr()</code> giving the image an incorrect <code>sizes</code> attribute, resulting in an oversized image being served. This fixes this issue. See ticket in WordPress Core Trac <a href="https://core.trac.wordpress.org/ticket/59352">#59352</a>.
* Plugin URI: https://gist.github.com/westonruter/f37f747a57643462b7efe110dd61d91b
* Version: 0.1.0
* Author: Weston Ruter
* Author URI: https://weston.ruter.net/
* License: GNU General Public License v2 (or later)
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
* Update URI: https://gist.github.com/westonruter/f37f747a57643462b7efe110dd61d91b
*/
namespace InlineImageSizeFix;
use WP_HTML_Tag_Processor;
/**
* Fixes size of inline images.
*
* @param string $content String
* @return string Fixed content.
*/
function fix_inline_image_size( string $content ): string {
$p = new WP_HTML_Tag_Processor( $content );
while ( $p->next_tag( array( 'tag_name' => 'IMG' ) ) ) {
// Note this filter runs before wp_filter_content_tags so the width and height are not added yet.
$src = $p->get_attribute( 'src' );
$style = $p->get_attribute( 'style' );
if (
! $src ||
$p->get_attribute( 'width' ) ||
$p->get_attribute( 'height' ) ||
! preg_match( '/^width:\s*(\d+)px;$/', $style, $style_matches ) ||
! preg_match( '/^wp-image-(\d+)$/', $p->get_attribute( 'class' ), $class_matches )
) {
continue;
}
$style_width = (int) $style_matches[1];
$attachment_id = (int) $class_matches[1];
if ( 0 === $attachment_id || 0 === $style_width ) {
continue;
}
// Obtain the width and height as is done in wp_img_tag_add_width_and_height_attr().
$image_meta = wp_get_attachment_metadata( $attachment_id );
if ( ! $image_meta ) {
continue;
}
$size_array = wp_image_src_get_dimensions( $src, $image_meta, $attachment_id );
if ( ! $size_array ) {
continue;
}
$new_height = ( $style_width / $size_array[0] ) * $size_array[1];
$new_width = $style_width;
$p->set_attribute( 'width', $new_width );
$p->set_attribute( 'height', ceil( $new_height ) );
$style .= sprintf( 'height: %fpx;', $new_height ); // Since the height may be fractional now.
$p->set_attribute( 'style', $style );
}
return $p->get_updated_html();
}
add_filter(
'the_content',
__NAMESPACE__ . '\fix_inline_image_size',
has_filter( 'the_content', 'wp_filter_content_tags' ) - 1
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment