Last active
September 14, 2023 22:46
-
-
Save westonruter/f37f747a57643462b7efe110dd61d91b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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