Skip to content

Commit 63b2544

Browse files
committed
Separate file structure by feature
1 parent 7f3e44d commit 63b2544

File tree

5 files changed

+291
-270
lines changed

5 files changed

+291
-270
lines changed

plugins/auto-sizes/auto-sizes.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@
2727

2828
define( 'IMAGE_AUTO_SIZES_VERSION', '1.3.0' );
2929

30+
require_once __DIR__ . '/inc/auto-sizes.php';
31+
require_once __DIR__ . '/inc/improve-calculate-sizes.php';
3032
require_once __DIR__ . '/hooks.php';

plugins/auto-sizes/hooks.php

Lines changed: 7 additions & 269 deletions
Original file line numberDiff line numberDiff line change
@@ -10,102 +10,6 @@
1010
exit; // Exit if accessed directly.
1111
}
1212

13-
/**
14-
* Adds auto to the sizes attribute to the image, if applicable.
15-
*
16-
* @since 1.0.0
17-
*
18-
* @param array<string, string>|mixed $attr Attributes for the image markup.
19-
* @return array<string, string> The filtered attributes for the image markup.
20-
*/
21-
function auto_sizes_update_image_attributes( $attr ): array {
22-
if ( ! is_array( $attr ) ) {
23-
$attr = array();
24-
}
25-
26-
// Bail early if the image is not lazy-loaded.
27-
if ( ! isset( $attr['loading'] ) || 'lazy' !== $attr['loading'] ) {
28-
return $attr;
29-
}
30-
31-
// Bail early if the image is not responsive.
32-
if ( ! isset( $attr['sizes'] ) ) {
33-
return $attr;
34-
}
35-
36-
// Don't add 'auto' to the sizes attribute if it already exists.
37-
if ( auto_sizes_attribute_includes_valid_auto( $attr['sizes'] ) ) {
38-
return $attr;
39-
}
40-
41-
$attr['sizes'] = 'auto, ' . $attr['sizes'];
42-
43-
return $attr;
44-
}
45-
46-
/**
47-
* Adds auto to the sizes attribute to the image, if applicable.
48-
*
49-
* @since 1.0.0
50-
*
51-
* @param string|mixed $html The HTML image tag markup being filtered.
52-
* @return string The filtered HTML image tag markup.
53-
*/
54-
function auto_sizes_update_content_img_tag( $html ): string {
55-
if ( ! is_string( $html ) ) {
56-
$html = '';
57-
}
58-
59-
$processor = new WP_HTML_Tag_Processor( $html );
60-
61-
// Bail if there is no IMG tag.
62-
if ( ! $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) {
63-
return $html;
64-
}
65-
66-
// Bail early if the image is not lazy-loaded.
67-
$value = $processor->get_attribute( 'loading' );
68-
if ( ! is_string( $value ) || 'lazy' !== strtolower( trim( $value, " \t\f\r\n" ) ) ) {
69-
return $html;
70-
}
71-
72-
$sizes = $processor->get_attribute( 'sizes' );
73-
74-
// Bail early if the image is not responsive.
75-
if ( ! is_string( $sizes ) ) {
76-
return $html;
77-
}
78-
79-
// Don't add 'auto' to the sizes attribute if it already exists.
80-
if ( auto_sizes_attribute_includes_valid_auto( $sizes ) ) {
81-
return $html;
82-
}
83-
84-
$processor->set_attribute( 'sizes', "auto, $sizes" );
85-
return $processor->get_updated_html();
86-
}
87-
88-
// Skip loading plugin filters if WordPress Core already loaded the functionality.
89-
if ( ! function_exists( 'wp_sizes_attribute_includes_valid_auto' ) ) {
90-
add_filter( 'wp_get_attachment_image_attributes', 'auto_sizes_update_image_attributes' );
91-
add_filter( 'wp_content_img_tag', 'auto_sizes_update_content_img_tag' );
92-
}
93-
94-
/**
95-
* Checks whether the given 'sizes' attribute includes the 'auto' keyword as the first item in the list.
96-
*
97-
* Per the HTML spec, if present it must be the first entry.
98-
*
99-
* @since 1.2.0
100-
*
101-
* @param string $sizes_attr The 'sizes' attribute value.
102-
* @return bool True if the 'auto' keyword is present, false otherwise.
103-
*/
104-
function auto_sizes_attribute_includes_valid_auto( string $sizes_attr ): bool {
105-
list( $first_size ) = explode( ',', $sizes_attr, 2 );
106-
return 'auto' === strtolower( trim( $first_size, " \t\f\r\n" ) );
107-
}
108-
10913
/**
11014
* Displays the HTML generator tag for the plugin.
11115
*
@@ -120,183 +24,17 @@ function auto_sizes_render_generator(): void {
12024
add_action( 'wp_head', 'auto_sizes_render_generator' );
12125

12226
/**
123-
* Gets the smaller image size if the layout width is bigger.
124-
*
125-
* It will return the smaller image size and return "px" if the layout width
126-
* is something else, e.g. min(640px, 90vw) or 90vw.
127-
*
128-
* @since 1.1.0
129-
*
130-
* @param string $layout_width The layout width.
131-
* @param int $image_width The image width.
132-
* @return string The proper width after some calculations.
133-
*/
134-
function auto_sizes_get_width( string $layout_width, int $image_width ): string {
135-
if ( str_ends_with( $layout_width, 'px' ) ) {
136-
return $image_width > (int) $layout_width ? $layout_width : $image_width . 'px';
137-
}
138-
return $image_width . 'px';
139-
}
140-
141-
/**
142-
* Primes attachment into the cache with a single database query.
143-
*
144-
* @since n.e.x.t
145-
*
146-
* @param string|mixed $content The HTML content.
147-
* @return string The HTML content.
27+
* Filters related to the auto-sizes functionality.
14828
*/
149-
function auto_sizes_prime_attachment_caches( $content ): string {
150-
if ( ! is_string( $content ) ) {
151-
return '';
152-
}
153-
154-
$processor = new WP_HTML_Tag_Processor( $content );
155-
156-
$images = array();
157-
while ( $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) {
158-
$class = $processor->get_attribute( 'class' );
159-
160-
if ( ! is_string( $class ) ) {
161-
continue;
162-
}
163-
164-
if ( preg_match( '/(?:^|\s)wp-image-([1-9][0-9]*)(?:\s|$)/', $class, $class_id ) === 1 ) {
165-
$attachment_id = (int) $class_id[1];
166-
if ( $attachment_id > 0 ) {
167-
$images[] = $attachment_id;
168-
}
169-
}
170-
}
171-
172-
// Reduce the array to unique attachment IDs.
173-
$attachment_ids = array_unique( $images );
174-
175-
if ( count( $attachment_ids ) > 1 ) {
176-
/*
177-
* Warm the object cache with post and meta information for all found
178-
* images to avoid making individual database calls.
179-
*/
180-
_prime_post_caches( $attachment_ids, false, true );
181-
}
182-
183-
return $content;
29+
// Skip loading plugin filters if WordPress Core already loaded the functionality.
30+
if ( ! function_exists( 'wp_img_tag_add_auto_sizes' ) ) {
31+
add_filter( 'wp_get_attachment_image_attributes', 'auto_sizes_update_image_attributes' );
32+
add_filter( 'wp_content_img_tag', 'auto_sizes_update_content_img_tag' );
18433
}
18534

186-
// This must run before 'do_blocks', which runs at priority 9.
187-
add_filter( 'the_content', 'auto_sizes_prime_attachment_caches', 9 );
188-
18935
/**
190-
* Filter the sizes attribute for images to improve the default calculation.
191-
*
192-
* @since 1.1.0
193-
*
194-
* @param string|mixed $content The block content about to be rendered.
195-
* @param array{ attrs?: array{ align?: string, width?: string } } $parsed_block The parsed block.
196-
* @param WP_Block $block Block instance.
197-
* @return string The updated block content.
36+
* Filters related to the improved image sizes functionality.
19837
*/
199-
function auto_sizes_filter_image_tag( $content, array $parsed_block, WP_Block $block ): string {
200-
if ( ! is_string( $content ) ) {
201-
return '';
202-
}
203-
$processor = new WP_HTML_Tag_Processor( $content );
204-
$has_image = $processor->next_tag( array( 'tag_name' => 'IMG' ) );
205-
206-
// Only update the markup if an image is found.
207-
if ( $has_image ) {
208-
209-
/**
210-
* Callback for calculating image sizes attribute value for an image block.
211-
*
212-
* This is a workaround to use block context data when calculating the img sizes attribute.
213-
*
214-
* @param string $sizes The image sizes attribute value.
215-
* @param string $size The image size data.
216-
*/
217-
$filter = static function ( $sizes, $size ) use ( $block ) {
218-
$id = $block->attributes['id'] ?? 0;
219-
$alignment = $block->attributes['align'] ?? '';
220-
$width = $block->attributes['width'] ?? '';
221-
222-
return auto_sizes_calculate_better_sizes( (int) $id, (string) $size, (string) $alignment, (string) $width );
223-
};
224-
225-
// Hook this filter early, before default filters are run.
226-
add_filter( 'wp_calculate_image_sizes', $filter, 9, 2 );
227-
228-
$sizes = wp_calculate_image_sizes(
229-
// If we don't have a size slug, assume the full size was used.
230-
$parsed_block['attrs']['sizeSlug'] ?? 'full',
231-
null,
232-
null,
233-
$parsed_block['attrs']['id'] ?? 0
234-
);
235-
236-
remove_filter( 'wp_calculate_image_sizes', $filter, 9 );
237-
238-
// Bail early if sizes are not calculated.
239-
if ( false === $sizes ) {
240-
return $content;
241-
}
242-
243-
$processor->set_attribute( 'sizes', $sizes );
244-
245-
return $processor->get_updated_html();
246-
}
247-
248-
return $content;
249-
}
38+
add_filter( 'the_content', 'auto_sizes_prime_attachment_caches', 9 ); // This must run before 'do_blocks', which runs at priority 9.
25039
add_filter( 'render_block_core/image', 'auto_sizes_filter_image_tag', 10, 3 );
25140
add_filter( 'render_block_core/cover', 'auto_sizes_filter_image_tag', 10, 3 );
252-
253-
/**
254-
* Modifies the sizes attribute of an image based on layout context.
255-
*
256-
* @param int $id The image id.
257-
* @param string $size The image size data.
258-
* @param string $align The image alignment.
259-
* @param string $resize_width Resize image width.
260-
* @return string The sizes attribute value.
261-
*/
262-
function auto_sizes_calculate_better_sizes( int $id, string $size, string $align, string $resize_width ): string {
263-
$sizes = '';
264-
$image = wp_get_attachment_image_src( $id, $size );
265-
266-
if ( false === $image ) {
267-
return $sizes;
268-
}
269-
270-
// Retrieve width from the image tag itself.
271-
$image_width = '' !== $resize_width ? (int) $resize_width : $image[1];
272-
273-
$layout = wp_get_global_settings( array( 'layout' ) );
274-
275-
// Handle different alignment use cases.
276-
switch ( $align ) {
277-
case 'full':
278-
$sizes = '100vw';
279-
break;
280-
281-
case 'wide':
282-
if ( array_key_exists( 'wideSize', $layout ) ) {
283-
$sizes = sprintf( '(max-width: %1$s) 100vw, %1$s', $layout['wideSize'] );
284-
}
285-
break;
286-
287-
case 'left':
288-
case 'right':
289-
case 'center':
290-
$sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $image_width );
291-
break;
292-
293-
default:
294-
if ( array_key_exists( 'contentSize', $layout ) ) {
295-
$width = auto_sizes_get_width( $layout['contentSize'], $image_width );
296-
$sizes = sprintf( '(max-width: %1$s) 100vw, %1$s', $width );
297-
}
298-
break;
299-
}
300-
301-
return $sizes;
302-
}

plugins/auto-sizes/inc/auto-sizes.php

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
/**
3+
* Functionality to implement auto-sizes for lazy loaded images.
4+
*
5+
* @package auto-sizes
6+
* @since n.e.x.t
7+
*/
8+
9+
/**
10+
* Adds auto to the sizes attribute to the image, if applicable.
11+
*
12+
* @since 1.0.0
13+
*
14+
* @param array<string, string>|mixed $attr Attributes for the image markup.
15+
* @return array<string, string> The filtered attributes for the image markup.
16+
*/
17+
function auto_sizes_update_image_attributes( $attr ): array {
18+
if ( ! is_array( $attr ) ) {
19+
$attr = array();
20+
}
21+
22+
// Bail early if the image is not lazy-loaded.
23+
if ( ! isset( $attr['loading'] ) || 'lazy' !== $attr['loading'] ) {
24+
return $attr;
25+
}
26+
27+
// Bail early if the image is not responsive.
28+
if ( ! isset( $attr['sizes'] ) ) {
29+
return $attr;
30+
}
31+
32+
// Don't add 'auto' to the sizes attribute if it already exists.
33+
if ( auto_sizes_attribute_includes_valid_auto( $attr['sizes'] ) ) {
34+
return $attr;
35+
}
36+
37+
$attr['sizes'] = 'auto, ' . $attr['sizes'];
38+
39+
return $attr;
40+
}
41+
42+
/**
43+
* Adds auto to the sizes attribute to the image, if applicable.
44+
*
45+
* @since 1.0.0
46+
*
47+
* @param string|mixed $html The HTML image tag markup being filtered.
48+
* @return string The filtered HTML image tag markup.
49+
*/
50+
function auto_sizes_update_content_img_tag( $html ): string {
51+
if ( ! is_string( $html ) ) {
52+
$html = '';
53+
}
54+
55+
$processor = new WP_HTML_Tag_Processor( $html );
56+
57+
// Bail if there is no IMG tag.
58+
if ( ! $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) {
59+
return $html;
60+
}
61+
62+
// Bail early if the image is not lazy-loaded.
63+
$value = $processor->get_attribute( 'loading' );
64+
if ( ! is_string( $value ) || 'lazy' !== strtolower( trim( $value, " \t\f\r\n" ) ) ) {
65+
return $html;
66+
}
67+
68+
$sizes = $processor->get_attribute( 'sizes' );
69+
70+
// Bail early if the image is not responsive.
71+
if ( ! is_string( $sizes ) ) {
72+
return $html;
73+
}
74+
75+
// Don't add 'auto' to the sizes attribute if it already exists.
76+
if ( auto_sizes_attribute_includes_valid_auto( $sizes ) ) {
77+
return $html;
78+
}
79+
80+
$processor->set_attribute( 'sizes', "auto, $sizes" );
81+
return $processor->get_updated_html();
82+
}
83+
84+
/**
85+
* Checks whether the given 'sizes' attribute includes the 'auto' keyword as the first item in the list.
86+
*
87+
* Per the HTML spec, if present it must be the first entry.
88+
*
89+
* @since 1.2.0
90+
*
91+
* @param string $sizes_attr The 'sizes' attribute value.
92+
* @return bool True if the 'auto' keyword is present, false otherwise.
93+
*/
94+
function auto_sizes_attribute_includes_valid_auto( string $sizes_attr ): bool {
95+
list( $first_size ) = explode( ',', $sizes_attr, 2 );
96+
return 'auto' === strtolower( trim( $first_size, " \t\f\r\n" ) );
97+
}

0 commit comments

Comments
 (0)